OpenTTD Source  20240917-master-g9ab0a47812
settings_gui.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
10 #include "stdafx.h"
11 #include "currency.h"
12 #include "error.h"
13 #include "settings_gui.h"
14 #include "textbuf_gui.h"
15 #include "command_func.h"
16 #include "network/network.h"
18 #include "town.h"
19 #include "settings_internal.h"
20 #include "strings_func.h"
21 #include "window_func.h"
22 #include "string_func.h"
23 #include "dropdown_type.h"
24 #include "dropdown_func.h"
25 #include "dropdown_common_type.h"
26 #include "slider_func.h"
27 #include "highscore.h"
28 #include "base_media_base.h"
29 #include "company_base.h"
30 #include "company_func.h"
31 #include "viewport_func.h"
32 #include "core/geometry_func.hpp"
33 #include "ai/ai.hpp"
34 #include "blitter/factory.hpp"
35 #include "language.h"
36 #include "textfile_gui.h"
37 #include "stringfilter_type.h"
38 #include "querystring_gui.h"
39 #include "fontcache.h"
40 #include "zoom_func.h"
41 #include "rev.h"
42 #include "video/video_driver.hpp"
43 #include "music/music_driver.hpp"
44 #include "gui.h"
45 #include "mixer.h"
46 #include "newgrf_config.h"
47 #include "network/core/config.h"
48 #include "network/network_gui.h"
49 #include "network/network_survey.h"
50 #include "video/video_driver.hpp"
51 #include "social_integration.h"
52 #include "sound_func.h"
53 
54 #include "safeguards.h"
55 
56 
57 #if defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA)
58 # define HAS_TRUETYPE_FONT
59 #endif
60 
61 static const StringID _autosave_dropdown[] = {
62  STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_OFF,
63  STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_10_MINUTES,
64  STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_30_MINUTES,
65  STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_60_MINUTES,
66  STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_120_MINUTES,
68 };
69 
71 static const uint32_t _autosave_dropdown_to_minutes[] = {
72  0,
73  10,
74  30,
75  60,
76  120,
77 };
78 
80 
81 static const void *ResolveObject(const GameSettings *settings_ptr, const IntSettingDesc *sd);
82 
88 {
89  auto it = std::find(_resolutions.begin(), _resolutions.end(), Dimension(_screen.width, _screen.height));
90  return std::distance(_resolutions.begin(), it);
91 }
92 
93 static void ShowCustCurrency();
94 
97  const std::string name;
99 
101  {
102  this->ConstructWindow();
103  this->LoadTextfile(textfile, BASESET_DIR);
104  }
105 
106  void SetStringParameters(WidgetID widget) const override
107  {
108  if (widget == WID_TF_CAPTION) {
110  SetDParamStr(1, this->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(file_type, baseset->name, *baseset->GetTextfile(file_type), content_type);
126 }
127 
128 template <class T>
129 DropDownList BuildSetDropDownList(int *selected_index)
130 {
131  int n = T::GetNumSets();
132  *selected_index = T::GetIndexOfUsedSet();
133  DropDownList list;
134  for (int i = 0; i < n; i++) {
135  list.push_back(MakeDropDownListStringItem(T::GetSet(i)->GetListLabel(), i));
136  }
137  return list;
138 }
139 
140 std::set<int> _refresh_rates = { 30, 60, 75, 90, 100, 120, 144, 240 };
141 
147 {
148  /* Add the refresh rate as selected in the config. */
149  _refresh_rates.insert(_settings_client.gui.refresh_rate);
150 
151  /* Add all the refresh rates of all monitors connected to the machine. */
152  std::vector<int> monitorRates = VideoDriver::GetInstance()->GetListOfMonitorRefreshRates();
153  std::copy(monitorRates.begin(), monitorRates.end(), std::inserter(_refresh_rates, _refresh_rates.end()));
154 }
155 
156 static const int SCALE_NMARKS = (MAX_INTERFACE_SCALE - MIN_INTERFACE_SCALE) / 25 + 1; // Show marks at 25% increments
157 static const int VOLUME_NMARKS = 9; // Show 5 values and 4 empty marks.
158 
159 static StringID ScaleMarkFunc(int, int, int value)
160 {
161  /* Label only every 100% mark. */
162  if (value % 100 != 0) return STR_NULL;
163 
164  SetDParam(0, value / 100);
165  SetDParam(1, 0);
166  return STR_GAME_OPTIONS_GUI_SCALE_MARK;
167 }
168 
169 static StringID VolumeMarkFunc(int, int mark, int value)
170 {
171  /* Label only every other mark. */
172  if (mark % 2 != 0) return STR_NULL;
173 
174  SetDParam(0, value / 31 * 25); // 0-127 does not map nicely to 0-100. Dividing first gives us nice round numbers.
175  return STR_GAME_OPTIONS_VOLUME_MARK;
176 }
177 
178 static constexpr NWidgetPart _nested_social_plugins_widgets[] = {
180  NWidget(WWT_FRAME, COLOUR_GREY, WID_GO_SOCIAL_PLUGIN_TITLE), SetDataTip(STR_JUST_STRING2, STR_NULL),
182  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_SOCIAL_PLUGIN_PLATFORM, STR_NULL),
183  NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_SOCIAL_PLUGIN_PLATFORM), SetMinimalSize(100, 12), SetDataTip(STR_JUST_RAW_STRING, STR_NULL), SetAlignment(SA_RIGHT),
184  EndContainer(),
186  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE, STR_NULL),
187  NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_SOCIAL_PLUGIN_STATE), SetMinimalSize(100, 12), SetDataTip(STR_JUST_STRING1, STR_NULL), SetAlignment(SA_RIGHT),
188  EndContainer(),
189  EndContainer(),
190  EndContainer(),
191 };
192 
193 static constexpr NWidgetPart _nested_social_plugins_none_widgets[] = {
195  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_SOCIAL_PLUGINS_NONE, STR_NULL),
196  EndContainer(),
197 };
198 
200 public:
202  {
203  this->plugins = SocialIntegration::GetPlugins();
204 
205  if (this->plugins.empty()) {
206  auto widget = MakeNWidgets(_nested_social_plugins_none_widgets, nullptr);
207  this->Add(std::move(widget));
208  } else {
209  for (size_t i = 0; i < this->plugins.size(); i++) {
210  auto widget = MakeNWidgets(_nested_social_plugins_widgets, nullptr);
211  this->Add(std::move(widget));
212  }
213  }
214 
215  this->SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0);
216  }
217 
218  void FillWidgetLookup(WidgetLookup &widget_lookup) override
219  {
220  widget_lookup[WID_GO_SOCIAL_PLUGINS] = this;
221  NWidgetVertical::FillWidgetLookup(widget_lookup);
222  }
223 
224  void SetupSmallestSize(Window *w) override
225  {
226  this->current_index = -1;
228  }
229 
236  template <typename T>
237  std::string &GetWidestPlugin(T SocialIntegrationPlugin::*member) const
238  {
239  std::string *longest = &(this->plugins[0]->*member);
240  int longest_length = 0;
241 
242  for (auto *plugin : this->plugins) {
243  int length = GetStringBoundingBox(plugin->*member).width;
244  if (length > longest_length) {
245  longest_length = length;
246  longest = &(plugin->*member);
247  }
248  }
249 
250  return *longest;
251  }
252 
253  void SetStringParameters(int widget) const
254  {
255  switch (widget) {
257  /* For SetupSmallestSize, use the longest string we have. */
258  if (this->current_index < 0) {
261  break;
262  }
263 
264  if (this->plugins[this->current_index]->name.empty()) {
265  SetDParam(0, STR_JUST_RAW_STRING);
266  SetDParamStr(1, this->plugins[this->current_index]->basepath);
267  } else {
268  SetDParam(0, STR_GAME_OPTIONS_SOCIAL_PLUGIN_TITLE);
269  SetDParamStr(1, this->plugins[this->current_index]->name);
270  SetDParamStr(2, this->plugins[this->current_index]->version);
271  }
272  break;
273 
275  /* For SetupSmallestSize, use the longest string we have. */
276  if (this->current_index < 0) {
278  break;
279  }
280 
281  SetDParamStr(0, this->plugins[this->current_index]->social_platform);
282  break;
283 
285  static const std::pair<SocialIntegrationPlugin::State, StringID> state_to_string[] = {
286  { SocialIntegrationPlugin::RUNNING, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_RUNNING },
287  { SocialIntegrationPlugin::FAILED, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_FAILED },
288  { SocialIntegrationPlugin::PLATFORM_NOT_RUNNING, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_PLATFORM_NOT_RUNNING },
289  { SocialIntegrationPlugin::UNLOADED, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_UNLOADED },
290  { SocialIntegrationPlugin::DUPLICATE, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_DUPLICATE },
291  { SocialIntegrationPlugin::UNSUPPORTED_API, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_UNSUPPORTED_API },
292  { SocialIntegrationPlugin::INVALID_SIGNATURE, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_INVALID_SIGNATURE },
293  };
294 
295  /* For SetupSmallestSize, use the longest string we have. */
296  if (this->current_index < 0) {
298 
299  /* Set the longest plugin when looking for the longest status. */
300  SetDParamStr(0, longest_plugin);
301 
302  StringID longest = STR_NULL;
303  int longest_length = 0;
304  for (auto state : state_to_string) {
305  int length = GetStringBoundingBox(state.second).width;
306  if (length > longest_length) {
307  longest_length = length;
308  longest = state.second;
309  }
310  }
311 
312  SetDParam(0, longest);
313  SetDParamStr(1, longest_plugin);
314  break;
315  }
316 
317  auto plugin = this->plugins[this->current_index];
318 
319  /* Default string, in case no state matches. */
320  SetDParam(0, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_FAILED);
321  SetDParamStr(1, plugin->social_platform);
322 
323  /* Find the string for the state. */
324  for (auto state : state_to_string) {
325  if (plugin->state == state.first) {
326  SetDParam(0, state.second);
327  break;
328  }
329  }
330  }
331  break;
332  }
333  }
334 
335  void Draw(const Window *w) override
336  {
337  this->current_index = 0;
338 
339  for (auto &wid : this->children) {
340  wid->Draw(w);
341  this->current_index++;
342  }
343  }
344 
345 private:
346  int current_index = -1;
347  std::vector<SocialIntegrationPlugin *> plugins;
348 };
349 
351 std::unique_ptr<NWidgetBase> MakeNWidgetSocialPlugins()
352 {
353  return std::make_unique<NWidgetSocialPlugins>();
354 }
355 
357  GameSettings *opt;
358  bool reload;
359  int gui_scale;
360  static inline WidgetID active_tab = WID_GO_TAB_GENERAL;
361 
362  GameOptionsWindow(WindowDesc &desc) : Window(desc)
363  {
364  this->opt = &GetGameSettings();
365  this->reload = false;
366  this->gui_scale = _gui_scale;
367 
369 
371  this->OnInvalidateData(0);
372 
373  this->SetTab(GameOptionsWindow::active_tab);
374 
375  if constexpr (!NetworkSurveyHandler::IsSurveyPossible()) this->GetWidget<NWidgetStacked>(WID_GO_SURVEY_SEL)->SetDisplayedPlane(SZSP_NONE);
376  }
377 
378  void Close([[maybe_unused]] int data = 0) override
379  {
382  if (this->reload) _switch_mode = SM_MENU;
383  this->Window::Close();
384  }
385 
392  DropDownList BuildDropDownList(WidgetID widget, int *selected_index) const
393  {
394  DropDownList list;
395  switch (widget) {
396  case WID_GO_CURRENCY_DROPDOWN: { // Setup currencies dropdown
397  *selected_index = this->opt->locale.currency;
398  uint64_t disabled = _game_mode == GM_MENU ? 0LL : ~GetMaskOfAllowedCurrencies();
399 
400  /* Add non-custom currencies; sorted naturally */
401  for (const CurrencySpec &currency : _currency_specs) {
402  int i = &currency - _currency_specs.data();
403  if (i == CURRENCY_CUSTOM) continue;
404  if (currency.code.empty()) {
405  list.push_back(MakeDropDownListStringItem(currency.name, i, HasBit(disabled, i)));
406  } else {
407  SetDParam(0, currency.name);
408  SetDParamStr(1, currency.code);
409  list.push_back(MakeDropDownListStringItem(STR_GAME_OPTIONS_CURRENCY_CODE, i, HasBit(disabled, i)));
410  }
411  }
412  std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc);
413 
414  /* Append custom currency at the end */
415  list.push_back(MakeDropDownListDividerItem()); // separator line
416  list.push_back(MakeDropDownListStringItem(STR_GAME_OPTIONS_CURRENCY_CUSTOM, CURRENCY_CUSTOM, HasBit(disabled, CURRENCY_CUSTOM)));
417  break;
418  }
419 
420  case WID_GO_AUTOSAVE_DROPDOWN: { // Setup autosave dropdown
421  int index = 0;
422  for (auto &minutes : _autosave_dropdown_to_minutes) {
423  index++;
424  if (_settings_client.gui.autosave_interval <= minutes) break;
425  }
426  *selected_index = index - 1;
427 
428  const StringID *items = _autosave_dropdown;
429  for (uint i = 0; *items != INVALID_STRING_ID; items++, i++) {
430  list.push_back(MakeDropDownListStringItem(*items, i));
431  }
432  break;
433  }
434 
435  case WID_GO_LANG_DROPDOWN: { // Setup interface language dropdown
436  for (uint i = 0; i < _languages.size(); i++) {
437  bool hide_language = IsReleasedVersion() && !_languages[i].IsReasonablyFinished();
438  if (hide_language) continue;
439  bool hide_percentage = IsReleasedVersion() || _languages[i].missing < _settings_client.gui.missing_strings_threshold;
440  if (&_languages[i] == _current_language) {
441  *selected_index = i;
442  SetDParamStr(0, _languages[i].own_name);
443  } else {
444  /* Especially with sprite-fonts, not all localized
445  * names can be rendered. So instead, we use the
446  * international names for anything but the current
447  * selected language. This avoids showing a few ????
448  * entries in the dropdown list. */
449  SetDParamStr(0, _languages[i].name);
450  }
451  SetDParam(1, (LANGUAGE_TOTAL_STRINGS - _languages[i].missing) * 100 / LANGUAGE_TOTAL_STRINGS);
452  list.push_back(MakeDropDownListStringItem(hide_percentage ? STR_JUST_RAW_STRING : STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE, i));
453  }
454  std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc);
455  break;
456  }
457 
458  case WID_GO_RESOLUTION_DROPDOWN: // Setup resolution dropdown
459  if (_resolutions.empty()) break;
460 
461  *selected_index = GetCurrentResolutionIndex();
462  for (uint i = 0; i < _resolutions.size(); i++) {
465  list.push_back(MakeDropDownListStringItem(STR_GAME_OPTIONS_RESOLUTION_ITEM, i));
466  }
467  break;
468 
469  case WID_GO_REFRESH_RATE_DROPDOWN: // Setup refresh rate dropdown
470  for (auto it = _refresh_rates.begin(); it != _refresh_rates.end(); it++) {
471  auto i = std::distance(_refresh_rates.begin(), it);
472  if (*it == _settings_client.gui.refresh_rate) *selected_index = i;
473  SetDParam(0, *it);
474  list.push_back(MakeDropDownListStringItem(STR_GAME_OPTIONS_REFRESH_RATE_ITEM, i));
475  }
476  break;
477 
479  list = BuildSetDropDownList<BaseGraphics>(selected_index);
480  break;
481 
483  list = BuildSetDropDownList<BaseSounds>(selected_index);
484  break;
485 
487  list = BuildSetDropDownList<BaseMusic>(selected_index);
488  break;
489  }
490 
491  return list;
492  }
493 
494  void SetStringParameters(WidgetID widget) const override
495  {
496  switch (widget) {
498  const CurrencySpec &currency = _currency_specs[this->opt->locale.currency];
499  if (currency.code.empty()) {
500  SetDParam(0, currency.name);
501  } else {
502  SetDParam(0, STR_GAME_OPTIONS_CURRENCY_CODE);
503  SetDParam(1, currency.name);
504  SetDParamStr(2, currency.code);
505  }
506  break;
507  }
509  int index = 0;
510  for (auto &minutes : _autosave_dropdown_to_minutes) {
511  index++;
512  if (_settings_client.gui.autosave_interval <= minutes) break;
513  }
514  SetDParam(0, _autosave_dropdown[index - 1]);
515  break;
516  }
518  case WID_GO_BASE_GRF_DROPDOWN: SetDParamStr(0, BaseGraphics::GetUsedSet()->GetListLabel()); break;
519  case WID_GO_BASE_SFX_DROPDOWN: SetDParamStr(0, BaseSounds::GetUsedSet()->GetListLabel()); break;
520  case WID_GO_BASE_MUSIC_DROPDOWN: SetDParamStr(0, BaseMusic::GetUsedSet()->GetListLabel()); break;
523  auto current_resolution = GetCurrentResolutionIndex();
524 
525  if (current_resolution == _resolutions.size()) {
526  SetDParam(0, STR_GAME_OPTIONS_RESOLUTION_OTHER);
527  } else {
528  SetDParam(0, STR_GAME_OPTIONS_RESOLUTION_ITEM);
529  SetDParam(1, _resolutions[current_resolution].width);
530  SetDParam(2, _resolutions[current_resolution].height);
531  }
532  break;
533  }
534 
538  const NWidgetSocialPlugins *plugin = this->GetWidget<NWidgetSocialPlugins>(WID_GO_SOCIAL_PLUGINS);
539  assert(plugin != nullptr);
540 
541  plugin->SetStringParameters(widget);
542  break;
543  }
544  }
545  }
546 
547  void DrawWidget(const Rect &r, WidgetID widget) const override
548  {
549  switch (widget) {
552  DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK);
553  break;
554 
557  DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK);
558  break;
559 
562  DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK);
563  break;
564 
565  case WID_GO_GUI_SCALE:
566  DrawSliderWidget(r, MIN_INTERFACE_SCALE, MAX_INTERFACE_SCALE, SCALE_NMARKS, this->gui_scale, ScaleMarkFunc);
567  break;
568 
570  SetDParamStr(0, std::string{VideoDriver::GetInstance()->GetInfoString()});
571  DrawStringMultiLine(r, STR_GAME_OPTIONS_VIDEO_DRIVER_INFO);
572  break;
573 
575  DrawSliderWidget(r, 0, INT8_MAX, VOLUME_NMARKS, _settings_client.music.effect_vol, VolumeMarkFunc);
576  break;
577 
579  DrawSliderWidget(r, 0, INT8_MAX, VOLUME_NMARKS, _settings_client.music.music_vol, VolumeMarkFunc);
580  break;
581  }
582  }
583 
584  void SetTab(WidgetID widget)
585  {
587  this->LowerWidget(widget);
588  GameOptionsWindow::active_tab = widget;
589 
590  int pane;
591  switch (widget) {
592  case WID_GO_TAB_GENERAL: pane = 0; break;
593  case WID_GO_TAB_GRAPHICS: pane = 1; break;
594  case WID_GO_TAB_SOUND: pane = 2; break;
595  case WID_GO_TAB_SOCIAL: pane = 3; break;
596  default: NOT_REACHED();
597  }
598 
599  this->GetWidget<NWidgetStacked>(WID_GO_TAB_SELECTION)->SetDisplayedPlane(pane);
600  this->SetDirty();
601  }
602 
603  void OnResize() override
604  {
605  bool changed = false;
606 
607  NWidgetResizeBase *wid = this->GetWidget<NWidgetResizeBase>(WID_GO_BASE_GRF_DESCRIPTION);
608  int y = 0;
609  for (int i = 0; i < BaseGraphics::GetNumSets(); i++) {
611  y = std::max(y, GetStringHeight(STR_JUST_RAW_STRING, wid->current_x));
612  }
613  changed |= wid->UpdateVerticalSize(y);
614 
615  wid = this->GetWidget<NWidgetResizeBase>(WID_GO_BASE_SFX_DESCRIPTION);
616  y = 0;
617  for (int i = 0; i < BaseSounds::GetNumSets(); i++) {
619  y = std::max(y, GetStringHeight(STR_JUST_RAW_STRING, wid->current_x));
620  }
621  changed |= wid->UpdateVerticalSize(y);
622 
623  wid = this->GetWidget<NWidgetResizeBase>(WID_GO_BASE_MUSIC_DESCRIPTION);
624  y = 0;
625  for (int i = 0; i < BaseMusic::GetNumSets(); i++) {
626  SetDParamStr(0, BaseMusic::GetSet(i)->GetDescription(GetCurrentLanguageIsoCode()));
627  y = std::max(y, GetStringHeight(STR_JUST_RAW_STRING, wid->current_x));
628  }
629  changed |= wid->UpdateVerticalSize(y);
630 
631  wid = this->GetWidget<NWidgetResizeBase>(WID_GO_VIDEO_DRIVER_INFO);
632  SetDParamStr(0, std::string{VideoDriver::GetInstance()->GetInfoString()});
633  y = GetStringHeight(STR_GAME_OPTIONS_VIDEO_DRIVER_INFO, wid->current_x);
634  changed |= wid->UpdateVerticalSize(y);
635 
636  if (changed) this->ReInit(0, 0, this->flags & WF_CENTERED);
637  }
638 
639  void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
640  {
641  switch (widget) {
644  Dimension d = maxdim(GetStringBoundingBox(STR_GAME_OPTIONS_SFX_VOLUME), GetStringBoundingBox(STR_GAME_OPTIONS_MUSIC_VOLUME));
645  d.width += padding.width;
646  d.height += padding.height;
647  size = maxdim(size, d);
648  break;
649  }
650 
659  int selected;
660  size.width = std::max(size.width, GetDropDownListDimension(this->BuildDropDownList(widget, &selected)).width + padding.width);
661  break;
662  }
663  }
664  }
665 
666  void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
667  {
668  if (widget >= WID_GO_BASE_GRF_TEXTFILE && widget < WID_GO_BASE_GRF_TEXTFILE + TFT_CONTENT_END) {
669  if (BaseGraphics::GetUsedSet() == nullptr) return;
670 
671  ShowBaseSetTextfileWindow((TextfileType)(widget - WID_GO_BASE_GRF_TEXTFILE), BaseGraphics::GetUsedSet(), STR_CONTENT_TYPE_BASE_GRAPHICS);
672  return;
673  }
674  if (widget >= WID_GO_BASE_SFX_TEXTFILE && widget < WID_GO_BASE_SFX_TEXTFILE + TFT_CONTENT_END) {
675  if (BaseSounds::GetUsedSet() == nullptr) return;
676 
677  ShowBaseSetTextfileWindow((TextfileType)(widget - WID_GO_BASE_SFX_TEXTFILE), BaseSounds::GetUsedSet(), STR_CONTENT_TYPE_BASE_SOUNDS);
678  return;
679  }
680  if (widget >= WID_GO_BASE_MUSIC_TEXTFILE && widget < WID_GO_BASE_MUSIC_TEXTFILE + TFT_CONTENT_END) {
681  if (BaseMusic::GetUsedSet() == nullptr) return;
682 
683  ShowBaseSetTextfileWindow((TextfileType)(widget - WID_GO_BASE_MUSIC_TEXTFILE), BaseMusic::GetUsedSet(), STR_CONTENT_TYPE_BASE_MUSIC);
684  return;
685  }
686  switch (widget) {
687  case WID_GO_TAB_GENERAL:
688  case WID_GO_TAB_GRAPHICS:
689  case WID_GO_TAB_SOUND:
690  case WID_GO_TAB_SOCIAL:
691  this->SetTab(widget);
692  break;
693 
696  case PS_ASK:
697  case PS_NO:
699  break;
700 
701  case PS_YES:
703  break;
704  }
705 
708  break;
709 
711  OpenBrowser(NETWORK_SURVEY_DETAILS_LINK);
712  break;
713 
715  ShowSurveyResultTextfileWindow();
716  break;
717 
718  case WID_GO_FULLSCREEN_BUTTON: // Click fullscreen on/off
719  /* try to toggle full-screen on/off */
720  if (!ToggleFullScreen(!_fullscreen)) {
721  ShowErrorMessage(STR_ERROR_FULLSCREEN_FAILED, INVALID_STRING_ID, WL_ERROR);
722  }
725  break;
726 
729  ShowErrorMessage(STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART, INVALID_STRING_ID, WL_INFO);
732 #ifndef __APPLE__
736 #endif
737  break;
738 
740  if (!_video_hw_accel) break;
741 
744 
749  break;
750 
753 
755  this->SetDirty();
756 
758  ReInitAllWindows(true);
759  break;
760  }
761 
762 #ifdef HAS_TRUETYPE_FONT
764  _fcsettings.prefer_sprite = !_fcsettings.prefer_sprite;
765 
768  this->SetDirty();
769 
770  InitFontCache(false);
771  InitFontCache(true);
772  ClearFontCache();
776  ReInitAllWindows(true);
777  break;
778 
779  case WID_GO_GUI_FONT_AA:
780  _fcsettings.global_aa = !_fcsettings.global_aa;
781 
784 
785  ClearFontCache();
786  break;
787 #endif /* HAS_TRUETYPE_FONT */
788 
789  case WID_GO_GUI_SCALE:
790  if (ClickSliderWidget(this->GetWidget<NWidgetBase>(widget)->GetCurrentRect(), pt, MIN_INTERFACE_SCALE, MAX_INTERFACE_SCALE, _ctrl_pressed ? 0 : SCALE_NMARKS, this->gui_scale)) {
791  this->SetWidgetDirty(widget);
792  }
793 
794  if (click_count > 0) this->mouse_capture_widget = widget;
795  break;
796 
798  {
799  if (_gui_scale_cfg == -1) {
802  } else {
803  _gui_scale_cfg = -1;
805  if (AdjustGUIZoom(false)) ReInitAllWindows(true);
806  this->gui_scale = _gui_scale;
807  }
808  this->SetWidgetDirty(widget);
809  break;
810  }
811 
813  auto *used_set = BaseGraphics::GetUsedSet();
814  if (used_set == nullptr || !used_set->IsConfigurable()) break;
815  GRFConfig &extra_cfg = used_set->GetOrCreateExtraConfig();
816  if (extra_cfg.num_params == 0) extra_cfg.SetParameterDefaults();
817  OpenGRFParameterWindow(true, &extra_cfg, _game_mode == GM_MENU);
818  if (_game_mode == GM_MENU) this->reload = true;
819  break;
820  }
821 
825  if (ClickSliderWidget(this->GetWidget<NWidgetBase>(widget)->GetCurrentRect(), pt, 0, INT8_MAX, 0, vol)) {
826  if (widget == WID_GO_BASE_MUSIC_VOLUME) {
828  } else {
829  SetEffectVolume(vol);
830  }
831  this->SetWidgetDirty(widget);
833  }
834 
835  if (click_count > 0) this->mouse_capture_widget = widget;
836  break;
837  }
838 
840  ShowMusicWindow();
841  break;
842  }
843 
845  if (BaseGraphics::GetUsedSet() == nullptr || BaseGraphics::GetUsedSet()->url.empty()) return;
846  OpenBrowser(BaseGraphics::GetUsedSet()->url);
847  break;
848 
850  if (BaseSounds::GetUsedSet() == nullptr || BaseSounds::GetUsedSet()->url.empty()) return;
851  OpenBrowser(BaseSounds::GetUsedSet()->url);
852  break;
853 
855  if (BaseMusic::GetUsedSet() == nullptr || BaseMusic::GetUsedSet()->url.empty()) return;
856  OpenBrowser(BaseMusic::GetUsedSet()->url);
857  break;
858 
861  break;
862 
865  break;
866 
869  break;
870 
879  int selected;
880  DropDownList list = this->BuildDropDownList(widget, &selected);
881  if (!list.empty()) {
882  ShowDropDownList(this, std::move(list), selected, widget);
883  } else {
884  if (widget == WID_GO_RESOLUTION_DROPDOWN) ShowErrorMessage(STR_ERROR_RESOLUTION_LIST_FAILED, INVALID_STRING_ID, WL_ERROR);
885  }
886  break;
887  }
888  }
889  }
890 
891  void OnMouseLoop() override
892  {
893  if (_left_button_down || this->gui_scale == _gui_scale) return;
894 
895  _gui_scale_cfg = this->gui_scale;
896 
897  if (AdjustGUIZoom(false)) {
898  ReInitAllWindows(true);
900  this->SetDirty();
901  }
902  }
903 
904  void OnDropdownSelect(WidgetID widget, int index) override
905  {
906  switch (widget) {
907  case WID_GO_CURRENCY_DROPDOWN: // Currency
908  if (index == CURRENCY_CUSTOM) ShowCustCurrency();
909  this->opt->locale.currency = index;
910  ReInitAllWindows(false);
911  break;
912 
913  case WID_GO_AUTOSAVE_DROPDOWN: // Autosave options
916  this->SetDirty();
917  break;
918 
919  case WID_GO_LANG_DROPDOWN: // Change interface language
920  ReadLanguagePack(&_languages[index]);
923  ClearAllCachedNames();
925  CheckBlitter();
926  ReInitAllWindows(false);
927  break;
928 
929  case WID_GO_RESOLUTION_DROPDOWN: // Change resolution
930  if ((uint)index < _resolutions.size() && ChangeResInGame(_resolutions[index].width, _resolutions[index].height)) {
931  this->SetDirty();
932  }
933  break;
934 
936  _settings_client.gui.refresh_rate = *std::next(_refresh_rates.begin(), index);
937  if (_settings_client.gui.refresh_rate > 60) {
938  /* Show warning to the user that this refresh rate might not be suitable on
939  * larger maps with many NewGRFs and vehicles. */
940  ShowErrorMessage(STR_GAME_OPTIONS_REFRESH_RATE_WARNING, INVALID_STRING_ID, WL_INFO);
941  }
942  break;
943  }
944 
946  if (_game_mode == GM_MENU) {
948  auto set = BaseGraphics::GetSet(index);
950  this->reload = true;
951  this->InvalidateData();
952  }
953  break;
954 
956  ChangeSoundSet(index);
957  break;
958 
960  ChangeMusicSet(index);
961  break;
962  }
963  }
964 
970  void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
971  {
972  if (!gui_scope) return;
977 
978 #ifndef __APPLE__
981 #endif
982 
985 #ifdef HAS_TRUETYPE_FONT
989 #endif /* HAS_TRUETYPE_FONT */
990 
991  this->SetWidgetDisabledState(WID_GO_BASE_GRF_DROPDOWN, _game_mode != GM_MENU);
992 
994 
998 
999  for (TextfileType tft = TFT_CONTENT_BEGIN; tft < TFT_CONTENT_END; tft++) {
1003  }
1004 
1006  }
1007 };
1008 
1009 static constexpr NWidgetPart _nested_game_options_widgets[] = {
1011  NWidget(WWT_CLOSEBOX, COLOUR_GREY),
1012  NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1013  EndContainer(),
1014  NWidget(WWT_PANEL, COLOUR_GREY),
1016  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),
1017  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),
1018  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),
1019  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),
1020  EndContainer(),
1021  EndContainer(),
1022  NWidget(WWT_PANEL, COLOUR_GREY),
1023  NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GO_TAB_SELECTION),
1024  /* General tab */
1026  NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_LANGUAGE, STR_NULL),
1027  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),
1028  EndContainer(),
1029 
1030  NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_AUTOSAVE_FRAME, STR_NULL),
1031  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),
1032  EndContainer(),
1033 
1034  NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME, STR_NULL),
1035  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),
1036  EndContainer(),
1037 
1038  NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GO_SURVEY_SEL),
1039  NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_PARTICIPATE_SURVEY_FRAME, STR_NULL), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0),
1041  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_PARTICIPATE_SURVEY, STR_NULL),
1042  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_SURVEY_PARTICIPATE_BUTTON), SetAspect(WidgetDimensions::ASPECT_SETTINGS_BUTTON), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_PARTICIPATE_SURVEY_TOOLTIP),
1043  EndContainer(),
1045  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),
1046  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),
1047  EndContainer(),
1048  EndContainer(),
1049  EndContainer(),
1050  EndContainer(),
1051 
1052  /* Graphics tab */
1054  NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_GUI_SCALE_FRAME, STR_NULL),
1056  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),
1058  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_GUI_SCALE_AUTO, STR_NULL),
1059  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_GUI_SCALE_AUTO), SetAspect(WidgetDimensions::ASPECT_SETTINGS_BUTTON), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP),
1060  EndContainer(),
1062  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_GUI_SCALE_BEVELS, STR_NULL),
1063  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_GUI_SCALE_BEVEL_BUTTON), SetAspect(WidgetDimensions::ASPECT_SETTINGS_BUTTON), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP),
1064  EndContainer(),
1065 #ifdef HAS_TRUETYPE_FONT
1067  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_GUI_FONT_SPRITE, STR_NULL),
1068  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_GUI_FONT_SPRITE), SetAspect(WidgetDimensions::ASPECT_SETTINGS_BUTTON), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_GUI_FONT_SPRITE_TOOLTIP),
1069  EndContainer(),
1071  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_GUI_FONT_AA, STR_NULL),
1072  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_GUI_FONT_AA), SetAspect(WidgetDimensions::ASPECT_SETTINGS_BUTTON), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_GUI_FONT_AA_TOOLTIP),
1073  EndContainer(),
1074 #endif /* HAS_TRUETYPE_FONT */
1075  EndContainer(),
1076  EndContainer(),
1077 
1078  NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_GRAPHICS, STR_NULL),
1081  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_RESOLUTION, STR_NULL),
1082  NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_RESOLUTION_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_JUST_STRING2, STR_GAME_OPTIONS_RESOLUTION_TOOLTIP),
1083  EndContainer(),
1085  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_REFRESH_RATE, STR_NULL),
1086  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),
1087  EndContainer(),
1089  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_FULLSCREEN, STR_NULL),
1090  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_FULLSCREEN_BUTTON), SetAspect(WidgetDimensions::ASPECT_SETTINGS_BUTTON), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP),
1091  EndContainer(),
1093  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_VIDEO_ACCELERATION, STR_NULL),
1094  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_VIDEO_ACCEL_BUTTON), SetAspect(WidgetDimensions::ASPECT_SETTINGS_BUTTON), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_VIDEO_ACCELERATION_TOOLTIP),
1095  EndContainer(),
1096 #ifndef __APPLE__
1098  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_VIDEO_VSYNC, STR_NULL),
1099  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_VIDEO_VSYNC_BUTTON), SetAspect(WidgetDimensions::ASPECT_SETTINGS_BUTTON), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP),
1100  EndContainer(),
1101 #endif
1103  NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_VIDEO_DRIVER_INFO), SetMinimalTextLines(1, 0), SetFill(1, 0),
1104  EndContainer(),
1105  EndContainer(),
1106  EndContainer(),
1107 
1108  NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_GRF, STR_NULL), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0), SetFill(1, 0),
1110  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),
1111  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_PARAMETERS), SetDataTip(STR_NEWGRF_SETTINGS_SET_PARAMETERS, STR_NULL),
1112  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_CONTENT_DOWNLOAD), SetDataTip(STR_GAME_OPTIONS_ONLINE_CONTENT, STR_GAME_OPTIONS_ONLINE_CONTENT_TOOLTIP),
1113  EndContainer(),
1114  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),
1117  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),
1118  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),
1119  EndContainer(),
1121  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),
1122  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),
1123  EndContainer(),
1124  EndContainer(),
1125  EndContainer(),
1126  EndContainer(),
1127 
1128  /* Sound/Music tab */
1130  NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_VOLUME, STR_NULL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0),
1132  NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_TEXT_SFX_VOLUME), SetMinimalSize(0, 12), SetDataTip(STR_GAME_OPTIONS_SFX_VOLUME, STR_NULL),
1133  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),
1134  EndContainer(),
1136  NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_TEXT_MUSIC_VOLUME), SetMinimalSize(0, 12), SetDataTip(STR_GAME_OPTIONS_MUSIC_VOLUME, STR_NULL),
1137  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),
1138  EndContainer(),
1139  EndContainer(),
1140 
1141  NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_SFX, STR_NULL), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0),
1143  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),
1144  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_CONTENT_DOWNLOAD), SetDataTip(STR_GAME_OPTIONS_ONLINE_CONTENT, STR_GAME_OPTIONS_ONLINE_CONTENT_TOOLTIP),
1145  EndContainer(),
1146  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),
1149  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),
1150  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),
1151  EndContainer(),
1153  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),
1154  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),
1155  EndContainer(),
1156  EndContainer(),
1157  EndContainer(),
1158 
1159  NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_MUSIC, STR_NULL), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0),
1161  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),
1162  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_CONTENT_DOWNLOAD), SetDataTip(STR_GAME_OPTIONS_ONLINE_CONTENT, STR_GAME_OPTIONS_ONLINE_CONTENT_TOOLTIP),
1163  EndContainer(),
1165  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),
1166  NWidget(NWID_VERTICAL), SetPIPRatio(0, 0, 1),
1167  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_JUKEBOX), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_MUSIC, STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW),
1168  EndContainer(),
1169  EndContainer(),
1172  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),
1173  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),
1174  EndContainer(),
1176  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),
1177  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),
1178  EndContainer(),
1179  EndContainer(),
1180  EndContainer(),
1181  EndContainer(),
1182 
1183  /* Social tab */
1186  EndContainer(),
1187  EndContainer(),
1188  EndContainer(),
1189 };
1190 
1191 static WindowDesc _game_options_desc(
1192  WDP_CENTER, nullptr, 0, 0,
1194  0,
1195  _nested_game_options_widgets
1196 );
1197 
1200 {
1202  new GameOptionsWindow(_game_options_desc);
1203 }
1204 
1205 static int SETTING_HEIGHT = 11;
1206 
1215 
1217  SEF_FILTERED = 0x08,
1218 };
1219 
1228 };
1230 
1231 
1235  bool type_hides;
1238 };
1239 
1242  uint8_t flags;
1243  uint8_t level;
1244 
1245  BaseSettingEntry() : flags(0), level(0) {}
1246  virtual ~BaseSettingEntry() = default;
1247 
1248  virtual void Init(uint8_t level = 0);
1249  virtual void FoldAll() {}
1250  virtual void UnFoldAll() {}
1251  virtual void ResetAll() = 0;
1252 
1257  void SetLastField(bool last_field) { if (last_field) SETBITS(this->flags, SEF_LAST_FIELD); else CLRBITS(this->flags, SEF_LAST_FIELD); }
1258 
1259  virtual uint Length() const = 0;
1260  virtual void GetFoldingState([[maybe_unused]] bool &all_folded, [[maybe_unused]] bool &all_unfolded) const {}
1261  virtual bool IsVisible(const BaseSettingEntry *item) const;
1262  virtual BaseSettingEntry *FindEntry(uint row, uint *cur_row);
1263  virtual uint GetMaxHelpHeight([[maybe_unused]] int maxw) { return 0; }
1264 
1269  bool IsFiltered() const { return (this->flags & SEF_FILTERED) != 0; }
1270 
1271  virtual bool UpdateFilterState(SettingFilter &filter, bool force_visible) = 0;
1272 
1273  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;
1274 
1275 protected:
1276  virtual void DrawSetting(GameSettings *settings_ptr, int left, int right, int y, bool highlight) const = 0;
1277 };
1278 
1281  const char *name;
1283 
1284  SettingEntry(const char *name);
1285 
1286  void Init(uint8_t level = 0) override;
1287  void ResetAll() override;
1288  uint Length() const override;
1289  uint GetMaxHelpHeight(int maxw) override;
1290  bool UpdateFilterState(SettingFilter &filter, bool force_visible) override;
1291 
1292  void SetButtons(uint8_t new_val);
1293 
1294 protected:
1295  void DrawSetting(GameSettings *settings_ptr, int left, int right, int y, bool highlight) const override;
1296 
1297 private:
1299 };
1300 
1303  typedef std::vector<BaseSettingEntry*> EntryVector;
1304  EntryVector entries;
1305 
1306  template<typename T>
1307  T *Add(T *item)
1308  {
1309  this->entries.push_back(item);
1310  return item;
1311  }
1312 
1313  void Init(uint8_t level = 0);
1314  void ResetAll();
1315  void FoldAll();
1316  void UnFoldAll();
1317 
1318  uint Length() const;
1319  void GetFoldingState(bool &all_folded, bool &all_unfolded) const;
1320  bool IsVisible(const BaseSettingEntry *item) const;
1321  BaseSettingEntry *FindEntry(uint row, uint *cur_row);
1322  uint GetMaxHelpHeight(int maxw);
1323 
1324  bool UpdateFilterState(SettingFilter &filter, bool force_visible);
1325 
1326  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;
1327 };
1328 
1332  bool folded;
1333 
1335 
1336  void Init(uint8_t level = 0) override;
1337  void ResetAll() override;
1338  void FoldAll() override;
1339  void UnFoldAll() override;
1340 
1341  uint Length() const override;
1342  void GetFoldingState(bool &all_folded, bool &all_unfolded) const override;
1343  bool IsVisible(const BaseSettingEntry *item) const override;
1344  BaseSettingEntry *FindEntry(uint row, uint *cur_row) override;
1345  uint GetMaxHelpHeight(int maxw) override { return SettingsContainer::GetMaxHelpHeight(maxw); }
1346 
1347  bool UpdateFilterState(SettingFilter &filter, bool force_visible) override;
1348 
1349  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;
1350 
1351 protected:
1352  void DrawSetting(GameSettings *settings_ptr, int left, int right, int y, bool highlight) const override;
1353 };
1354 
1355 /* == BaseSettingEntry methods == */
1356 
1361 void BaseSettingEntry::Init(uint8_t level)
1362 {
1363  this->level = level;
1364 }
1365 
1373 {
1374  if (this->IsFiltered()) return false;
1375  return this == item;
1376 }
1377 
1384 BaseSettingEntry *BaseSettingEntry::FindEntry(uint row_num, uint *cur_row)
1385 {
1386  if (this->IsFiltered()) return nullptr;
1387  if (row_num == *cur_row) return this;
1388  (*cur_row)++;
1389  return nullptr;
1390 }
1391 
1421 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
1422 {
1423  if (this->IsFiltered()) return cur_row;
1424  if (cur_row >= max_row) return cur_row;
1425 
1426  bool rtl = _current_text_dir == TD_RTL;
1427  int offset = (rtl ? -(int)_circle_size.width : (int)_circle_size.width) / 2;
1429 
1430  int x = rtl ? right : left;
1431  if (cur_row >= first_row) {
1432  int colour = GetColourGradient(COLOUR_ORANGE, SHADE_NORMAL);
1433  y += (cur_row - first_row) * SETTING_HEIGHT; // Compute correct y start position
1434 
1435  /* Draw vertical for parent nesting levels */
1436  for (uint lvl = 0; lvl < this->level; lvl++) {
1437  if (!HasBit(parent_last, lvl)) GfxDrawLine(x + offset, y, x + offset, y + SETTING_HEIGHT - 1, colour);
1438  x += level_width;
1439  }
1440  /* draw own |- prefix */
1441  int halfway_y = y + SETTING_HEIGHT / 2;
1442  int bottom_y = (flags & SEF_LAST_FIELD) ? halfway_y : y + SETTING_HEIGHT - 1;
1443  GfxDrawLine(x + offset, y, x + offset, bottom_y, colour);
1444  /* Small horizontal line from the last vertical line */
1445  GfxDrawLine(x + offset, halfway_y, x + level_width - (rtl ? -WidgetDimensions::scaled.hsep_normal : WidgetDimensions::scaled.hsep_normal), halfway_y, colour);
1446  x += level_width;
1447 
1448  this->DrawSetting(settings_ptr, rtl ? left : x, rtl ? x : right, y, this == selected);
1449  }
1450  cur_row++;
1451 
1452  return cur_row;
1453 }
1454 
1455 /* == SettingEntry methods == */
1456 
1462 {
1463  this->name = name;
1464  this->setting = nullptr;
1465 }
1466 
1471 void SettingEntry::Init(uint8_t level)
1472 {
1474  this->setting = GetSettingFromName(this->name)->AsIntSetting();
1475 }
1476 
1477 /* Sets the given setting entry to its default value */
1478 void SettingEntry::ResetAll()
1479 {
1480  SetSettingValue(this->setting, this->setting->def);
1481 }
1482 
1488 void SettingEntry::SetButtons(uint8_t new_val)
1489 {
1490  assert((new_val & ~SEF_BUTTONS_MASK) == 0); // Should not touch any flags outside the buttons
1491  this->flags = (this->flags & ~SEF_BUTTONS_MASK) | new_val;
1492 }
1493 
1496 {
1497  return this->IsFiltered() ? 0 : 1;
1498 }
1499 
1506 {
1507  return GetStringHeight(this->setting->GetHelp(), maxw);
1508 }
1509 
1516 {
1517  /* There shall not be any restriction, i.e. all settings shall be visible. */
1518  if (mode == RM_ALL) return true;
1519 
1520  const IntSettingDesc *sd = this->setting;
1521 
1522  if (mode == RM_BASIC) return (this->setting->cat & SC_BASIC_LIST) != 0;
1523  if (mode == RM_ADVANCED) return (this->setting->cat & SC_ADVANCED_LIST) != 0;
1524 
1525  /* Read the current value. */
1526  const void *object = ResolveObject(&GetGameSettings(), sd);
1527  int64_t current_value = sd->Read(object);
1528  int64_t filter_value;
1529 
1530  if (mode == RM_CHANGED_AGAINST_DEFAULT) {
1531  /* This entry shall only be visible, if the value deviates from its default value. */
1532 
1533  /* Read the default value. */
1534  filter_value = sd->def;
1535  } else {
1536  assert(mode == RM_CHANGED_AGAINST_NEW);
1537  /* This entry shall only be visible, if the value deviates from
1538  * its value is used when starting a new game. */
1539 
1540  /* Make sure we're not comparing the new game settings against itself. */
1541  assert(&GetGameSettings() != &_settings_newgame);
1542 
1543  /* Read the new game's value. */
1544  filter_value = sd->Read(ResolveObject(&_settings_newgame, sd));
1545  }
1546 
1547  return current_value != filter_value;
1548 }
1549 
1556 bool SettingEntry::UpdateFilterState(SettingFilter &filter, bool force_visible)
1557 {
1558  CLRBITS(this->flags, SEF_FILTERED);
1559 
1560  bool visible = true;
1561 
1562  const IntSettingDesc *sd = this->setting;
1563  if (!force_visible && !filter.string.IsEmpty()) {
1564  /* Process the search text filter for this item. */
1565  filter.string.ResetState();
1566 
1567  SetDParam(0, STR_EMPTY);
1568  filter.string.AddLine(sd->GetTitle());
1569  filter.string.AddLine(sd->GetHelp());
1570 
1571  visible = filter.string.GetState();
1572  }
1573 
1574  if (visible) {
1575  if (filter.type != ST_ALL && sd->GetType() != filter.type) {
1576  filter.type_hides = true;
1577  visible = false;
1578  }
1579  if (!this->IsVisibleByRestrictionMode(filter.mode)) {
1580  while (filter.min_cat < RM_ALL && (filter.min_cat == filter.mode || !this->IsVisibleByRestrictionMode(filter.min_cat))) filter.min_cat++;
1581  visible = false;
1582  }
1583  }
1584 
1585  if (!visible) SETBITS(this->flags, SEF_FILTERED);
1586  return visible;
1587 }
1588 
1589 static const void *ResolveObject(const GameSettings *settings_ptr, const IntSettingDesc *sd)
1590 {
1591  if ((sd->flags & SF_PER_COMPANY) != 0) {
1592  if (Company::IsValidID(_local_company) && _game_mode != GM_MENU) {
1593  return &Company::Get(_local_company)->settings;
1594  }
1595  return &_settings_client.company;
1596  }
1597  return settings_ptr;
1598 }
1599 
1608 void SettingEntry::DrawSetting(GameSettings *settings_ptr, int left, int right, int y, bool highlight) const
1609 {
1610  const IntSettingDesc *sd = this->setting;
1611  int state = this->flags & SEF_BUTTONS_MASK;
1612 
1613  bool rtl = _current_text_dir == TD_RTL;
1614  uint buttons_left = rtl ? right + 1 - SETTING_BUTTON_WIDTH : left;
1615  uint text_left = left + (rtl ? 0 : SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_wide);
1616  uint text_right = right - (rtl ? SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_wide : 0);
1617  uint button_y = y + (SETTING_HEIGHT - SETTING_BUTTON_HEIGHT) / 2;
1618 
1619  /* We do not allow changes of some items when we are a client in a networkgame */
1620  bool editable = sd->IsEditable();
1621 
1622  SetDParam(0, STR_CONFIG_SETTING_VALUE);
1623  int32_t value = sd->Read(ResolveObject(settings_ptr, sd));
1624  if (sd->IsBoolSetting()) {
1625  /* Draw checkbox for boolean-value either on/off */
1626  DrawBoolButton(buttons_left, button_y, value != 0, editable);
1627  } else if ((sd->flags & SF_GUI_DROPDOWN) != 0) {
1628  /* Draw [v] button for settings of an enum-type */
1629  DrawDropDownButton(buttons_left, button_y, COLOUR_YELLOW, state != 0, editable);
1630  } else {
1631  /* Draw [<][>] boxes for settings of an integer-type */
1632  DrawArrowButtons(buttons_left, button_y, COLOUR_YELLOW, state,
1633  editable && value != (sd->flags & SF_GUI_0_IS_SPECIAL ? 0 : sd->min), editable && (uint32_t)value != sd->max);
1634  }
1635  sd->SetValueDParams(1, value);
1636  DrawString(text_left, text_right, y + (SETTING_HEIGHT - GetCharacterHeight(FS_NORMAL)) / 2, sd->GetTitle(), highlight ? TC_WHITE : TC_LIGHT_BLUE);
1637 }
1638 
1639 /* == SettingsContainer methods == */
1640 
1645 void SettingsContainer::Init(uint8_t level)
1646 {
1647  for (auto &it : this->entries) {
1648  it->Init(level);
1649  }
1650 }
1651 
1654 {
1655  for (auto settings_entry : this->entries) {
1656  settings_entry->ResetAll();
1657  }
1658 }
1659 
1662 {
1663  for (auto &it : this->entries) {
1664  it->FoldAll();
1665  }
1666 }
1667 
1670 {
1671  for (auto &it : this->entries) {
1672  it->UnFoldAll();
1673  }
1674 }
1675 
1681 void SettingsContainer::GetFoldingState(bool &all_folded, bool &all_unfolded) const
1682 {
1683  for (auto &it : this->entries) {
1684  it->GetFoldingState(all_folded, all_unfolded);
1685  }
1686 }
1687 
1694 bool SettingsContainer::UpdateFilterState(SettingFilter &filter, bool force_visible)
1695 {
1696  bool visible = false;
1697  bool first_visible = true;
1698  for (EntryVector::reverse_iterator it = this->entries.rbegin(); it != this->entries.rend(); ++it) {
1699  visible |= (*it)->UpdateFilterState(filter, force_visible);
1700  (*it)->SetLastField(first_visible);
1701  if (visible && first_visible) first_visible = false;
1702  }
1703  return visible;
1704 }
1705 
1706 
1714 {
1715  for (const auto &it : this->entries) {
1716  if (it->IsVisible(item)) return true;
1717  }
1718  return false;
1719 }
1720 
1723 {
1724  uint length = 0;
1725  for (const auto &it : this->entries) {
1726  length += it->Length();
1727  }
1728  return length;
1729 }
1730 
1737 BaseSettingEntry *SettingsContainer::FindEntry(uint row_num, uint *cur_row)
1738 {
1739  BaseSettingEntry *pe = nullptr;
1740  for (const auto &it : this->entries) {
1741  pe = it->FindEntry(row_num, cur_row);
1742  if (pe != nullptr) {
1743  break;
1744  }
1745  }
1746  return pe;
1747 }
1748 
1755 {
1756  uint biggest = 0;
1757  for (const auto &it : this->entries) {
1758  biggest = std::max(biggest, it->GetMaxHelpHeight(maxw));
1759  }
1760  return biggest;
1761 }
1762 
1763 
1778 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
1779 {
1780  for (const auto &it : this->entries) {
1781  cur_row = it->Draw(settings_ptr, left, right, y, first_row, max_row, selected, cur_row, parent_last);
1782  if (cur_row >= max_row) break;
1783  }
1784  return cur_row;
1785 }
1786 
1787 /* == SettingsPage methods == */
1788 
1794 {
1795  this->title = title;
1796  this->folded = true;
1797 }
1798 
1803 void SettingsPage::Init(uint8_t level)
1804 {
1807 }
1808 
1811 {
1812  for (auto settings_entry : this->entries) {
1813  settings_entry->ResetAll();
1814  }
1815 }
1816 
1819 {
1820  if (this->IsFiltered()) return;
1821  this->folded = true;
1822 
1824 }
1825 
1828 {
1829  if (this->IsFiltered()) return;
1830  this->folded = false;
1831 
1833 }
1834 
1840 void SettingsPage::GetFoldingState(bool &all_folded, bool &all_unfolded) const
1841 {
1842  if (this->IsFiltered()) return;
1843 
1844  if (this->folded) {
1845  all_unfolded = false;
1846  } else {
1847  all_folded = false;
1848  }
1849 
1850  SettingsContainer::GetFoldingState(all_folded, all_unfolded);
1851 }
1852 
1859 bool SettingsPage::UpdateFilterState(SettingFilter &filter, bool force_visible)
1860 {
1861  if (!force_visible && !filter.string.IsEmpty()) {
1862  filter.string.ResetState();
1863  filter.string.AddLine(this->title);
1864  force_visible = filter.string.GetState();
1865  }
1866 
1867  bool visible = SettingsContainer::UpdateFilterState(filter, force_visible);
1868  if (visible) {
1869  CLRBITS(this->flags, SEF_FILTERED);
1870  } else {
1871  SETBITS(this->flags, SEF_FILTERED);
1872  }
1873  return visible;
1874 }
1875 
1883 {
1884  if (this->IsFiltered()) return false;
1885  if (this == item) return true;
1886  if (this->folded) return false;
1887 
1888  return SettingsContainer::IsVisible(item);
1889 }
1890 
1893 {
1894  if (this->IsFiltered()) return 0;
1895  if (this->folded) return 1; // Only displaying the title
1896 
1897  return 1 + SettingsContainer::Length();
1898 }
1899 
1906 BaseSettingEntry *SettingsPage::FindEntry(uint row_num, uint *cur_row)
1907 {
1908  if (this->IsFiltered()) return nullptr;
1909  if (row_num == *cur_row) return this;
1910  (*cur_row)++;
1911  if (this->folded) return nullptr;
1912 
1913  return SettingsContainer::FindEntry(row_num, cur_row);
1914 }
1915 
1930 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
1931 {
1932  if (this->IsFiltered()) return cur_row;
1933  if (cur_row >= max_row) return cur_row;
1934 
1935  cur_row = BaseSettingEntry::Draw(settings_ptr, left, right, y, first_row, max_row, selected, cur_row, parent_last);
1936 
1937  if (!this->folded) {
1938  if (this->flags & SEF_LAST_FIELD) {
1939  assert(this->level < 8 * sizeof(parent_last));
1940  SetBit(parent_last, this->level); // Add own last-field state
1941  }
1942 
1943  cur_row = SettingsContainer::Draw(settings_ptr, left, right, y, first_row, max_row, selected, cur_row, parent_last);
1944  }
1945 
1946  return cur_row;
1947 }
1948 
1955 void SettingsPage::DrawSetting(GameSettings *, int left, int right, int y, bool) const
1956 {
1957  bool rtl = _current_text_dir == TD_RTL;
1958  DrawSprite((this->folded ? SPR_CIRCLE_FOLDED : SPR_CIRCLE_UNFOLDED), PAL_NONE, rtl ? right - _circle_size.width : left, y + (SETTING_HEIGHT - _circle_size.height) / 2);
1959  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);
1960 }
1961 
1964 {
1965  static SettingsContainer *main = nullptr;
1966 
1967  if (main == nullptr)
1968  {
1969  /* Build up the dynamic settings-array only once per OpenTTD session */
1970  main = new SettingsContainer();
1971 
1972  SettingsPage *localisation = main->Add(new SettingsPage(STR_CONFIG_SETTING_LOCALISATION));
1973  {
1974  localisation->Add(new SettingEntry("locale.units_velocity"));
1975  localisation->Add(new SettingEntry("locale.units_velocity_nautical"));
1976  localisation->Add(new SettingEntry("locale.units_power"));
1977  localisation->Add(new SettingEntry("locale.units_weight"));
1978  localisation->Add(new SettingEntry("locale.units_volume"));
1979  localisation->Add(new SettingEntry("locale.units_force"));
1980  localisation->Add(new SettingEntry("locale.units_height"));
1981  localisation->Add(new SettingEntry("gui.date_format_in_default_names"));
1982  }
1983 
1984  SettingsPage *graphics = main->Add(new SettingsPage(STR_CONFIG_SETTING_GRAPHICS));
1985  {
1986  graphics->Add(new SettingEntry("gui.zoom_min"));
1987  graphics->Add(new SettingEntry("gui.zoom_max"));
1988  graphics->Add(new SettingEntry("gui.sprite_zoom_min"));
1989  graphics->Add(new SettingEntry("gui.smallmap_land_colour"));
1990  graphics->Add(new SettingEntry("gui.linkgraph_colours"));
1991  graphics->Add(new SettingEntry("gui.graph_line_thickness"));
1992  }
1993 
1994  SettingsPage *sound = main->Add(new SettingsPage(STR_CONFIG_SETTING_SOUND));
1995  {
1996  sound->Add(new SettingEntry("sound.click_beep"));
1997  sound->Add(new SettingEntry("sound.confirm"));
1998  sound->Add(new SettingEntry("sound.news_ticker"));
1999  sound->Add(new SettingEntry("sound.news_full"));
2000  sound->Add(new SettingEntry("sound.new_year"));
2001  sound->Add(new SettingEntry("sound.disaster"));
2002  sound->Add(new SettingEntry("sound.vehicle"));
2003  sound->Add(new SettingEntry("sound.ambient"));
2004  }
2005 
2006  SettingsPage *interface = main->Add(new SettingsPage(STR_CONFIG_SETTING_INTERFACE));
2007  {
2008  SettingsPage *general = interface->Add(new SettingsPage(STR_CONFIG_SETTING_INTERFACE_GENERAL));
2009  {
2010  general->Add(new SettingEntry("gui.osk_activation"));
2011  general->Add(new SettingEntry("gui.hover_delay_ms"));
2012  general->Add(new SettingEntry("gui.errmsg_duration"));
2013  general->Add(new SettingEntry("gui.window_snap_radius"));
2014  general->Add(new SettingEntry("gui.window_soft_limit"));
2015  general->Add(new SettingEntry("gui.right_click_wnd_close"));
2016  }
2017 
2018  SettingsPage *viewports = interface->Add(new SettingsPage(STR_CONFIG_SETTING_INTERFACE_VIEWPORTS));
2019  {
2020  viewports->Add(new SettingEntry("gui.auto_scrolling"));
2021  viewports->Add(new SettingEntry("gui.scroll_mode"));
2022  viewports->Add(new SettingEntry("gui.smooth_scroll"));
2023  /* While the horizontal scrollwheel scrolling is written as general code, only
2024  * the cocoa (OSX) driver generates input for it.
2025  * Since it's also able to completely disable the scrollwheel will we display it on all platforms anyway */
2026  viewports->Add(new SettingEntry("gui.scrollwheel_scrolling"));
2027  viewports->Add(new SettingEntry("gui.scrollwheel_multiplier"));
2028 #ifdef __APPLE__
2029  /* We might need to emulate a right mouse button on mac */
2030  viewports->Add(new SettingEntry("gui.right_mouse_btn_emulation"));
2031 #endif
2032  viewports->Add(new SettingEntry("gui.population_in_label"));
2033  viewports->Add(new SettingEntry("gui.liveries"));
2034  viewports->Add(new SettingEntry("construction.train_signal_side"));
2035  viewports->Add(new SettingEntry("gui.measure_tooltip"));
2036  viewports->Add(new SettingEntry("gui.loading_indicators"));
2037  viewports->Add(new SettingEntry("gui.show_track_reservation"));
2038  }
2039 
2040  SettingsPage *construction = interface->Add(new SettingsPage(STR_CONFIG_SETTING_INTERFACE_CONSTRUCTION));
2041  {
2042  construction->Add(new SettingEntry("gui.link_terraform_toolbar"));
2043  construction->Add(new SettingEntry("gui.persistent_buildingtools"));
2044  construction->Add(new SettingEntry("gui.default_rail_type"));
2045  construction->Add(new SettingEntry("gui.semaphore_build_before"));
2046  construction->Add(new SettingEntry("gui.signal_gui_mode"));
2047  construction->Add(new SettingEntry("gui.cycle_signal_types"));
2048  construction->Add(new SettingEntry("gui.drag_signals_fixed_distance"));
2049  construction->Add(new SettingEntry("gui.auto_remove_signals"));
2050  }
2051 
2052  interface->Add(new SettingEntry("gui.toolbar_pos"));
2053  interface->Add(new SettingEntry("gui.statusbar_pos"));
2054  interface->Add(new SettingEntry("gui.prefer_teamchat"));
2055  interface->Add(new SettingEntry("gui.advanced_vehicle_list"));
2056  interface->Add(new SettingEntry("gui.timetable_mode"));
2057  interface->Add(new SettingEntry("gui.timetable_arrival_departure"));
2058  interface->Add(new SettingEntry("gui.show_newgrf_name"));
2059  interface->Add(new SettingEntry("gui.show_cargo_in_vehicle_lists"));
2060  }
2061 
2062  SettingsPage *advisors = main->Add(new SettingsPage(STR_CONFIG_SETTING_ADVISORS));
2063  {
2064  advisors->Add(new SettingEntry("gui.coloured_news_year"));
2065  advisors->Add(new SettingEntry("news_display.general"));
2066  advisors->Add(new SettingEntry("news_display.new_vehicles"));
2067  advisors->Add(new SettingEntry("news_display.accident"));
2068  advisors->Add(new SettingEntry("news_display.accident_other"));
2069  advisors->Add(new SettingEntry("news_display.company_info"));
2070  advisors->Add(new SettingEntry("news_display.acceptance"));
2071  advisors->Add(new SettingEntry("news_display.arrival_player"));
2072  advisors->Add(new SettingEntry("news_display.arrival_other"));
2073  advisors->Add(new SettingEntry("news_display.advice"));
2074  advisors->Add(new SettingEntry("gui.order_review_system"));
2075  advisors->Add(new SettingEntry("gui.vehicle_income_warn"));
2076  advisors->Add(new SettingEntry("gui.lost_vehicle_warn"));
2077  advisors->Add(new SettingEntry("gui.old_vehicle_warn"));
2078  advisors->Add(new SettingEntry("gui.show_finances"));
2079  advisors->Add(new SettingEntry("news_display.economy"));
2080  advisors->Add(new SettingEntry("news_display.subsidies"));
2081  advisors->Add(new SettingEntry("news_display.open"));
2082  advisors->Add(new SettingEntry("news_display.close"));
2083  advisors->Add(new SettingEntry("news_display.production_player"));
2084  advisors->Add(new SettingEntry("news_display.production_other"));
2085  advisors->Add(new SettingEntry("news_display.production_nobody"));
2086  }
2087 
2088  SettingsPage *company = main->Add(new SettingsPage(STR_CONFIG_SETTING_COMPANY));
2089  {
2090  company->Add(new SettingEntry("gui.starting_colour"));
2091  company->Add(new SettingEntry("gui.starting_colour_secondary"));
2092  company->Add(new SettingEntry("company.engine_renew"));
2093  company->Add(new SettingEntry("company.engine_renew_months"));
2094  company->Add(new SettingEntry("company.engine_renew_money"));
2095  company->Add(new SettingEntry("vehicle.servint_ispercent"));
2096  company->Add(new SettingEntry("vehicle.servint_trains"));
2097  company->Add(new SettingEntry("vehicle.servint_roadveh"));
2098  company->Add(new SettingEntry("vehicle.servint_ships"));
2099  company->Add(new SettingEntry("vehicle.servint_aircraft"));
2100  }
2101 
2102  SettingsPage *accounting = main->Add(new SettingsPage(STR_CONFIG_SETTING_ACCOUNTING));
2103  {
2104  accounting->Add(new SettingEntry("difficulty.infinite_money"));
2105  accounting->Add(new SettingEntry("economy.inflation"));
2106  accounting->Add(new SettingEntry("difficulty.initial_interest"));
2107  accounting->Add(new SettingEntry("difficulty.max_loan"));
2108  accounting->Add(new SettingEntry("difficulty.subsidy_multiplier"));
2109  accounting->Add(new SettingEntry("difficulty.subsidy_duration"));
2110  accounting->Add(new SettingEntry("economy.feeder_payment_share"));
2111  accounting->Add(new SettingEntry("economy.infrastructure_maintenance"));
2112  accounting->Add(new SettingEntry("difficulty.vehicle_costs"));
2113  accounting->Add(new SettingEntry("difficulty.construction_cost"));
2114  }
2115 
2116  SettingsPage *vehicles = main->Add(new SettingsPage(STR_CONFIG_SETTING_VEHICLES));
2117  {
2118  SettingsPage *physics = vehicles->Add(new SettingsPage(STR_CONFIG_SETTING_VEHICLES_PHYSICS));
2119  {
2120  physics->Add(new SettingEntry("vehicle.train_acceleration_model"));
2121  physics->Add(new SettingEntry("vehicle.train_slope_steepness"));
2122  physics->Add(new SettingEntry("vehicle.wagon_speed_limits"));
2123  physics->Add(new SettingEntry("vehicle.freight_trains"));
2124  physics->Add(new SettingEntry("vehicle.roadveh_acceleration_model"));
2125  physics->Add(new SettingEntry("vehicle.roadveh_slope_steepness"));
2126  physics->Add(new SettingEntry("vehicle.smoke_amount"));
2127  physics->Add(new SettingEntry("vehicle.plane_speed"));
2128  }
2129 
2130  SettingsPage *routing = vehicles->Add(new SettingsPage(STR_CONFIG_SETTING_VEHICLES_ROUTING));
2131  {
2132  routing->Add(new SettingEntry("vehicle.road_side"));
2133  routing->Add(new SettingEntry("difficulty.line_reverse_mode"));
2134  routing->Add(new SettingEntry("pf.reverse_at_signals"));
2135  routing->Add(new SettingEntry("pf.forbid_90_deg"));
2136  }
2137 
2138  SettingsPage *orders = vehicles->Add(new SettingsPage(STR_CONFIG_SETTING_VEHICLES_ORDERS));
2139  {
2140  orders->Add(new SettingEntry("gui.new_nonstop"));
2141  orders->Add(new SettingEntry("gui.quick_goto"));
2142  orders->Add(new SettingEntry("gui.stop_location"));
2143  }
2144  }
2145 
2146  SettingsPage *limitations = main->Add(new SettingsPage(STR_CONFIG_SETTING_LIMITATIONS));
2147  {
2148  limitations->Add(new SettingEntry("construction.command_pause_level"));
2149  limitations->Add(new SettingEntry("construction.autoslope"));
2150  limitations->Add(new SettingEntry("construction.extra_dynamite"));
2151  limitations->Add(new SettingEntry("construction.map_height_limit"));
2152  limitations->Add(new SettingEntry("construction.max_bridge_length"));
2153  limitations->Add(new SettingEntry("construction.max_bridge_height"));
2154  limitations->Add(new SettingEntry("construction.max_tunnel_length"));
2155  limitations->Add(new SettingEntry("station.never_expire_airports"));
2156  limitations->Add(new SettingEntry("vehicle.never_expire_vehicles"));
2157  limitations->Add(new SettingEntry("vehicle.max_trains"));
2158  limitations->Add(new SettingEntry("vehicle.max_roadveh"));
2159  limitations->Add(new SettingEntry("vehicle.max_aircraft"));
2160  limitations->Add(new SettingEntry("vehicle.max_ships"));
2161  limitations->Add(new SettingEntry("vehicle.max_train_length"));
2162  limitations->Add(new SettingEntry("station.station_spread"));
2163  limitations->Add(new SettingEntry("station.distant_join_stations"));
2164  limitations->Add(new SettingEntry("station.modified_catchment"));
2165  limitations->Add(new SettingEntry("construction.road_stop_on_town_road"));
2166  limitations->Add(new SettingEntry("construction.road_stop_on_competitor_road"));
2167  limitations->Add(new SettingEntry("construction.crossing_with_competitor"));
2168  limitations->Add(new SettingEntry("vehicle.disable_elrails"));
2169  limitations->Add(new SettingEntry("order.station_length_loading_penalty"));
2170  }
2171 
2172  SettingsPage *disasters = main->Add(new SettingsPage(STR_CONFIG_SETTING_ACCIDENTS));
2173  {
2174  disasters->Add(new SettingEntry("difficulty.disasters"));
2175  disasters->Add(new SettingEntry("difficulty.economy"));
2176  disasters->Add(new SettingEntry("vehicle.plane_crashes"));
2177  disasters->Add(new SettingEntry("difficulty.vehicle_breakdowns"));
2178  disasters->Add(new SettingEntry("order.no_servicing_if_no_breakdowns"));
2179  disasters->Add(new SettingEntry("order.serviceathelipad"));
2180  }
2181 
2182  SettingsPage *genworld = main->Add(new SettingsPage(STR_CONFIG_SETTING_GENWORLD));
2183  {
2184  genworld->Add(new SettingEntry("game_creation.landscape"));
2185  genworld->Add(new SettingEntry("game_creation.land_generator"));
2186  genworld->Add(new SettingEntry("difficulty.terrain_type"));
2187  genworld->Add(new SettingEntry("game_creation.tgen_smoothness"));
2188  genworld->Add(new SettingEntry("game_creation.variety"));
2189  genworld->Add(new SettingEntry("game_creation.snow_coverage"));
2190  genworld->Add(new SettingEntry("game_creation.snow_line_height"));
2191  genworld->Add(new SettingEntry("game_creation.desert_coverage"));
2192  genworld->Add(new SettingEntry("game_creation.amount_of_rivers"));
2193  }
2194 
2195  SettingsPage *environment = main->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT));
2196  {
2197  SettingsPage *time = environment->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT_TIME));
2198  {
2199  time->Add(new SettingEntry("economy.timekeeping_units"));
2200  time->Add(new SettingEntry("economy.minutes_per_calendar_year"));
2201  time->Add(new SettingEntry("game_creation.ending_year"));
2202  time->Add(new SettingEntry("gui.pause_on_newgame"));
2203  time->Add(new SettingEntry("gui.fast_forward_speed_limit"));
2204  }
2205 
2206  SettingsPage *authorities = environment->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT_AUTHORITIES));
2207  {
2208  authorities->Add(new SettingEntry("difficulty.town_council_tolerance"));
2209  authorities->Add(new SettingEntry("economy.bribe"));
2210  authorities->Add(new SettingEntry("economy.exclusive_rights"));
2211  authorities->Add(new SettingEntry("economy.fund_roads"));
2212  authorities->Add(new SettingEntry("economy.fund_buildings"));
2213  authorities->Add(new SettingEntry("economy.station_noise_level"));
2214  }
2215 
2216  SettingsPage *towns = environment->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT_TOWNS));
2217  {
2218  towns->Add(new SettingEntry("economy.town_cargo_scale"));
2219  towns->Add(new SettingEntry("economy.town_growth_rate"));
2220  towns->Add(new SettingEntry("economy.allow_town_roads"));
2221  towns->Add(new SettingEntry("economy.allow_town_level_crossings"));
2222  towns->Add(new SettingEntry("economy.found_town"));
2223  towns->Add(new SettingEntry("economy.town_layout"));
2224  towns->Add(new SettingEntry("economy.larger_towns"));
2225  towns->Add(new SettingEntry("economy.initial_city_size"));
2226  towns->Add(new SettingEntry("economy.town_cargogen_mode"));
2227  }
2228 
2229  SettingsPage *industries = environment->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES));
2230  {
2231  industries->Add(new SettingEntry("economy.industry_cargo_scale"));
2232  industries->Add(new SettingEntry("difficulty.industry_density"));
2233  industries->Add(new SettingEntry("construction.raw_industry_construction"));
2234  industries->Add(new SettingEntry("construction.industry_platform"));
2235  industries->Add(new SettingEntry("economy.multiple_industry_per_town"));
2236  industries->Add(new SettingEntry("game_creation.oil_refinery_limit"));
2237  industries->Add(new SettingEntry("economy.type"));
2238  industries->Add(new SettingEntry("station.serve_neutral_industries"));
2239  }
2240 
2241  SettingsPage *cdist = environment->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST));
2242  {
2243  cdist->Add(new SettingEntry("linkgraph.recalc_time"));
2244  cdist->Add(new SettingEntry("linkgraph.recalc_interval"));
2245  cdist->Add(new SettingEntry("linkgraph.distribution_pax"));
2246  cdist->Add(new SettingEntry("linkgraph.distribution_mail"));
2247  cdist->Add(new SettingEntry("linkgraph.distribution_armoured"));
2248  cdist->Add(new SettingEntry("linkgraph.distribution_default"));
2249  cdist->Add(new SettingEntry("linkgraph.accuracy"));
2250  cdist->Add(new SettingEntry("linkgraph.demand_distance"));
2251  cdist->Add(new SettingEntry("linkgraph.demand_size"));
2252  cdist->Add(new SettingEntry("linkgraph.short_path_saturation"));
2253  }
2254 
2255  SettingsPage *trees = environment->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT_TREES));
2256  {
2257  trees->Add(new SettingEntry("game_creation.tree_placer"));
2258  trees->Add(new SettingEntry("construction.extra_tree_placement"));
2259  }
2260  }
2261 
2262  SettingsPage *ai = main->Add(new SettingsPage(STR_CONFIG_SETTING_AI));
2263  {
2264  SettingsPage *npc = ai->Add(new SettingsPage(STR_CONFIG_SETTING_AI_NPC));
2265  {
2266  npc->Add(new SettingEntry("script.script_max_opcode_till_suspend"));
2267  npc->Add(new SettingEntry("script.script_max_memory_megabytes"));
2268  npc->Add(new SettingEntry("difficulty.competitor_speed"));
2269  npc->Add(new SettingEntry("ai.ai_in_multiplayer"));
2270  npc->Add(new SettingEntry("ai.ai_disable_veh_train"));
2271  npc->Add(new SettingEntry("ai.ai_disable_veh_roadveh"));
2272  npc->Add(new SettingEntry("ai.ai_disable_veh_aircraft"));
2273  npc->Add(new SettingEntry("ai.ai_disable_veh_ship"));
2274  }
2275 
2276  ai->Add(new SettingEntry("economy.give_money"));
2277  }
2278 
2279  SettingsPage *network = main->Add(new SettingsPage(STR_CONFIG_SETTING_NETWORK));
2280  {
2281  network->Add(new SettingEntry("network.use_relay_service"));
2282  }
2283 
2284  main->Init();
2285  }
2286  return *main;
2287 }
2288 
2289 static const StringID _game_settings_restrict_dropdown[] = {
2290  STR_CONFIG_SETTING_RESTRICT_BASIC, // RM_BASIC
2291  STR_CONFIG_SETTING_RESTRICT_ADVANCED, // RM_ADVANCED
2292  STR_CONFIG_SETTING_RESTRICT_ALL, // RM_ALL
2293  STR_CONFIG_SETTING_RESTRICT_CHANGED_AGAINST_DEFAULT, // RM_CHANGED_AGAINST_DEFAULT
2294  STR_CONFIG_SETTING_RESTRICT_CHANGED_AGAINST_NEW, // RM_CHANGED_AGAINST_NEW
2295 };
2296 static_assert(lengthof(_game_settings_restrict_dropdown) == RM_END);
2297 
2304 };
2305 
2311 static void ResetAllSettingsConfirmationCallback(Window *w, bool confirmed)
2312 {
2313  if (confirmed) {
2316  w->InvalidateData();
2317  }
2318 }
2319 
2323 
2329 
2335 
2336  Scrollbar *vscroll;
2337 
2339  {
2340  this->warn_missing = WHR_NONE;
2341  this->warn_lines = 0;
2343  this->filter.min_cat = RM_ALL;
2344  this->filter.type = ST_ALL;
2345  this->filter.type_hides = false;
2346  this->settings_ptr = &GetGameSettings();
2347 
2348  GetSettingsTree().FoldAll(); // Close all sub-pages
2349 
2350  this->valuewindow_entry = nullptr; // No setting entry for which a entry window is opened
2351  this->clicked_entry = nullptr; // No numeric setting buttons are depressed
2352  this->last_clicked = nullptr;
2353  this->valuedropdown_entry = nullptr;
2354  this->closing_dropdown = false;
2355  this->manually_changed_folding = false;
2356 
2357  this->CreateNestedTree();
2358  this->vscroll = this->GetScrollbar(WID_GS_SCROLLBAR);
2360 
2361  this->querystrings[WID_GS_FILTER] = &this->filter_editbox;
2362  this->filter_editbox.cancel_button = QueryString::ACTION_CLEAR;
2364 
2365  this->InvalidateData();
2366  }
2367 
2368  void OnInit() override
2369  {
2370  _circle_size = maxdim(GetSpriteSize(SPR_CIRCLE_FOLDED), GetSpriteSize(SPR_CIRCLE_UNFOLDED));
2371  }
2372 
2373  void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
2374  {
2375  switch (widget) {
2376  case WID_GS_OPTIONSPANEL:
2378  resize.width = 1;
2379 
2380  size.height = 5 * resize.height + WidgetDimensions::scaled.framerect.Vertical();
2381  break;
2382 
2383  case WID_GS_HELP_TEXT: {
2384  static const StringID setting_types[] = {
2385  STR_CONFIG_SETTING_TYPE_CLIENT,
2386  STR_CONFIG_SETTING_TYPE_COMPANY_MENU, STR_CONFIG_SETTING_TYPE_COMPANY_INGAME,
2387  STR_CONFIG_SETTING_TYPE_GAME_MENU, STR_CONFIG_SETTING_TYPE_GAME_INGAME,
2388  };
2389  for (const auto &setting_type : setting_types) {
2390  SetDParam(0, setting_type);
2391  size.width = std::max(size.width, GetStringBoundingBox(STR_CONFIG_SETTING_TYPE).width + padding.width);
2392  }
2394  std::max(size.height, GetSettingsTree().GetMaxHelpHeight(size.width));
2395  break;
2396  }
2397 
2399  case WID_GS_RESTRICT_TYPE:
2400  size.width = std::max(GetStringBoundingBox(STR_CONFIG_SETTING_RESTRICT_CATEGORY).width, GetStringBoundingBox(STR_CONFIG_SETTING_RESTRICT_TYPE).width);
2401  break;
2402 
2403  default:
2404  break;
2405  }
2406  }
2407 
2408  void OnPaint() override
2409  {
2410  if (this->closing_dropdown) {
2411  this->closing_dropdown = false;
2412  assert(this->valuedropdown_entry != nullptr);
2413  this->valuedropdown_entry->SetButtons(0);
2414  this->valuedropdown_entry = nullptr;
2415  }
2416 
2417  /* Reserve the correct number of lines for the 'some search results are hidden' notice in the central settings display panel. */
2418  const Rect panel = this->GetWidget<NWidgetBase>(WID_GS_OPTIONSPANEL)->GetCurrentRect().Shrink(WidgetDimensions::scaled.frametext);
2419  StringID warn_str = STR_CONFIG_SETTING_CATEGORY_HIDES - 1 + this->warn_missing;
2420  int new_warn_lines;
2421  if (this->warn_missing == WHR_NONE) {
2422  new_warn_lines = 0;
2423  } else {
2424  SetDParam(0, _game_settings_restrict_dropdown[this->filter.min_cat]);
2425  new_warn_lines = GetStringLineCount(warn_str, panel.Width());
2426  }
2427  if (this->warn_lines != new_warn_lines) {
2428  this->vscroll->SetCount(this->vscroll->GetCount() - this->warn_lines + new_warn_lines);
2429  this->warn_lines = new_warn_lines;
2430  }
2431 
2432  this->DrawWidgets();
2433 
2434  /* Draw the 'some search results are hidden' notice. */
2435  if (this->warn_missing != WHR_NONE) {
2436  SetDParam(0, _game_settings_restrict_dropdown[this->filter.min_cat]);
2437  DrawStringMultiLine(panel.WithHeight(this->warn_lines * GetCharacterHeight(FS_NORMAL)), warn_str, TC_FROMSTRING, SA_CENTER);
2438  }
2439  }
2440 
2441  void SetStringParameters(WidgetID widget) const override
2442  {
2443  switch (widget) {
2445  SetDParam(0, _game_settings_restrict_dropdown[this->filter.mode]);
2446  break;
2447 
2448  case WID_GS_TYPE_DROPDOWN:
2449  switch (this->filter.type) {
2450  case ST_GAME: SetDParam(0, _game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME); break;
2451  case ST_COMPANY: SetDParam(0, _game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME); break;
2452  case ST_CLIENT: SetDParam(0, STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT); break;
2453  default: SetDParam(0, STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL); break;
2454  }
2455  break;
2456  }
2457  }
2458 
2459  DropDownList BuildDropDownList(WidgetID widget) const
2460  {
2461  DropDownList list;
2462  switch (widget) {
2464  for (int mode = 0; mode != RM_END; mode++) {
2465  /* If we are in adv. settings screen for the new game's settings,
2466  * we don't want to allow comparing with new game's settings. */
2467  bool disabled = mode == RM_CHANGED_AGAINST_NEW && settings_ptr == &_settings_newgame;
2468 
2469  list.push_back(MakeDropDownListStringItem(_game_settings_restrict_dropdown[mode], mode, disabled));
2470  }
2471  break;
2472 
2473  case WID_GS_TYPE_DROPDOWN:
2474  list.push_back(MakeDropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL, ST_ALL));
2475  list.push_back(MakeDropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME, ST_GAME));
2476  list.push_back(MakeDropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME, ST_COMPANY));
2477  list.push_back(MakeDropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT, ST_CLIENT));
2478  break;
2479  }
2480  return list;
2481  }
2482 
2483  void DrawWidget(const Rect &r, WidgetID widget) const override
2484  {
2485  switch (widget) {
2486  case WID_GS_OPTIONSPANEL: {
2487  Rect tr = r.Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect);
2488  tr.top += this->warn_lines * SETTING_HEIGHT;
2489  uint last_row = this->vscroll->GetPosition() + this->vscroll->GetCapacity() - this->warn_lines;
2490  int next_row = GetSettingsTree().Draw(settings_ptr, tr.left, tr.right, tr.top,
2491  this->vscroll->GetPosition(), last_row, this->last_clicked);
2492  if (next_row == 0) DrawString(tr, STR_CONFIG_SETTINGS_NONE);
2493  break;
2494  }
2495 
2496  case WID_GS_HELP_TEXT:
2497  if (this->last_clicked != nullptr) {
2498  const IntSettingDesc *sd = this->last_clicked->setting;
2499 
2500  Rect tr = r;
2501  switch (sd->GetType()) {
2502  case ST_COMPANY: SetDParam(0, _game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_COMPANY_INGAME); break;
2503  case ST_CLIENT: SetDParam(0, STR_CONFIG_SETTING_TYPE_CLIENT); break;
2504  case ST_GAME: SetDParam(0, _game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_GAME_MENU : STR_CONFIG_SETTING_TYPE_GAME_INGAME); break;
2505  default: NOT_REACHED();
2506  }
2507  DrawString(tr, STR_CONFIG_SETTING_TYPE);
2508  tr.top += GetCharacterHeight(FS_NORMAL);
2509 
2510  int32_t def_val = sd->get_def_cb != nullptr ? sd->get_def_cb() : sd->def;
2511  sd->SetValueDParams(0, def_val);
2512  DrawString(tr, STR_CONFIG_SETTING_DEFAULT_VALUE);
2514 
2515  DrawStringMultiLine(tr, sd->GetHelp(), TC_WHITE);
2516  }
2517  break;
2518 
2519  default:
2520  break;
2521  }
2522  }
2523 
2529  {
2530  if (this->last_clicked != pe) this->SetDirty();
2531  this->last_clicked = pe;
2532  }
2533 
2534  void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
2535  {
2536  switch (widget) {
2537  case WID_GS_EXPAND_ALL:
2538  this->manually_changed_folding = true;
2540  this->InvalidateData();
2541  break;
2542 
2543  case WID_GS_COLLAPSE_ALL:
2544  this->manually_changed_folding = true;
2546  this->InvalidateData();
2547  break;
2548 
2549  case WID_GS_RESET_ALL:
2550  ShowQuery(
2551  STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_CAPTION,
2552  STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_TEXT,
2553  this,
2555  );
2556  break;
2557 
2558  case WID_GS_RESTRICT_DROPDOWN: {
2559  DropDownList list = this->BuildDropDownList(widget);
2560  if (!list.empty()) {
2561  ShowDropDownList(this, std::move(list), this->filter.mode, widget);
2562  }
2563  break;
2564  }
2565 
2566  case WID_GS_TYPE_DROPDOWN: {
2567  DropDownList list = this->BuildDropDownList(widget);
2568  if (!list.empty()) {
2569  ShowDropDownList(this, std::move(list), this->filter.type, widget);
2570  }
2571  break;
2572  }
2573  }
2574 
2575  if (widget != WID_GS_OPTIONSPANEL) return;
2576 
2577  int32_t btn = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_GS_OPTIONSPANEL, WidgetDimensions::scaled.framerect.top);
2578  if (btn == INT32_MAX || btn < this->warn_lines) return;
2579  btn -= this->warn_lines;
2580 
2581  uint cur_row = 0;
2583 
2584  if (clicked_entry == nullptr) return; // Clicked below the last setting of the page
2585 
2586  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
2587  if (x < 0) return; // Clicked left of the entry
2588 
2589  SettingsPage *clicked_page = dynamic_cast<SettingsPage*>(clicked_entry);
2590  if (clicked_page != nullptr) {
2591  this->SetDisplayedHelpText(nullptr);
2592  clicked_page->folded = !clicked_page->folded; // Flip 'folded'-ness of the sub-page
2593 
2594  this->manually_changed_folding = true;
2595 
2596  this->InvalidateData();
2597  return;
2598  }
2599 
2600  SettingEntry *pe = dynamic_cast<SettingEntry*>(clicked_entry);
2601  assert(pe != nullptr);
2602  const IntSettingDesc *sd = pe->setting;
2603 
2604  /* return if action is only active in network, or only settable by server */
2605  if (!sd->IsEditable()) {
2606  this->SetDisplayedHelpText(pe);
2607  return;
2608  }
2609 
2610  int32_t value = sd->Read(ResolveObject(settings_ptr, sd));
2611 
2612  /* clicked on the icon on the left side. Either scroller, bool on/off or dropdown */
2613  if (x < SETTING_BUTTON_WIDTH && (sd->flags & SF_GUI_DROPDOWN)) {
2614  this->SetDisplayedHelpText(pe);
2615 
2616  if (this->valuedropdown_entry == pe) {
2617  /* unclick the dropdown */
2619  this->closing_dropdown = false;
2620  this->valuedropdown_entry->SetButtons(0);
2621  this->valuedropdown_entry = nullptr;
2622  } else {
2623  if (this->valuedropdown_entry != nullptr) this->valuedropdown_entry->SetButtons(0);
2624  this->closing_dropdown = false;
2625 
2626  const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_GS_OPTIONSPANEL);
2627  int rel_y = (pt.y - wid->pos_y - WidgetDimensions::scaled.framerect.top) % wid->resize_y;
2628 
2629  Rect wi_rect;
2630  wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x);
2631  wi_rect.right = wi_rect.left + SETTING_BUTTON_WIDTH - 1;
2632  wi_rect.top = pt.y - rel_y + (SETTING_HEIGHT - SETTING_BUTTON_HEIGHT) / 2;
2633  wi_rect.bottom = wi_rect.top + SETTING_BUTTON_HEIGHT - 1;
2634 
2635  /* For dropdowns we also have to check the y position thoroughly, the mouse may not above the just opening dropdown */
2636  if (pt.y >= wi_rect.top && pt.y <= wi_rect.bottom) {
2637  this->valuedropdown_entry = pe;
2638  this->valuedropdown_entry->SetButtons(SEF_LEFT_DEPRESSED);
2639 
2640  DropDownList list;
2641  for (int i = sd->min; i <= (int)sd->max; i++) {
2642  sd->SetValueDParams(0, i);
2643  list.push_back(MakeDropDownListStringItem(STR_JUST_STRING2, i));
2644  }
2645 
2646  ShowDropDownListAt(this, std::move(list), value, WID_GS_SETTING_DROPDOWN, wi_rect, COLOUR_ORANGE);
2647  }
2648  }
2649  this->SetDirty();
2650  } else if (x < SETTING_BUTTON_WIDTH) {
2651  this->SetDisplayedHelpText(pe);
2652  int32_t oldvalue = value;
2653 
2654  if (sd->IsBoolSetting()) {
2655  value ^= 1;
2656  } else {
2657  /* Add a dynamic step-size to the scroller. In a maximum of
2658  * 50-steps you should be able to get from min to max,
2659  * unless specified otherwise in the 'interval' variable
2660  * of the current setting. */
2661  uint32_t step = (sd->interval == 0) ? ((sd->max - sd->min) / 50) : sd->interval;
2662  if (step == 0) step = 1;
2663 
2664  /* don't allow too fast scrolling */
2665  if ((this->flags & WF_TIMEOUT) && this->timeout_timer > 1) {
2666  _left_button_clicked = false;
2667  return;
2668  }
2669 
2670  /* Increase or decrease the value and clamp it to extremes */
2671  if (x >= SETTING_BUTTON_WIDTH / 2) {
2672  value += step;
2673  if (sd->min < 0) {
2674  assert((int32_t)sd->max >= 0);
2675  if (value > (int32_t)sd->max) value = (int32_t)sd->max;
2676  } else {
2677  if ((uint32_t)value > sd->max) value = (int32_t)sd->max;
2678  }
2679  if (value < sd->min) value = sd->min; // skip between "disabled" and minimum
2680  } else {
2681  value -= step;
2682  if (value < sd->min) value = (sd->flags & SF_GUI_0_IS_SPECIAL) ? 0 : sd->min;
2683  }
2684 
2685  /* Set up scroller timeout for numeric values */
2686  if (value != oldvalue) {
2687  if (this->clicked_entry != nullptr) { // Release previous buttons if any
2688  this->clicked_entry->SetButtons(0);
2689  }
2690  this->clicked_entry = pe;
2691  this->clicked_entry->SetButtons((x >= SETTING_BUTTON_WIDTH / 2) != (_current_text_dir == TD_RTL) ? SEF_RIGHT_DEPRESSED : SEF_LEFT_DEPRESSED);
2692  this->SetTimeout();
2693  _left_button_clicked = false;
2694  }
2695  }
2696 
2697  if (value != oldvalue) {
2698  SetSettingValue(sd, value);
2699  this->SetDirty();
2700  }
2701  } else {
2702  /* Only open editbox if clicked for the second time, and only for types where it is sensible for. */
2703  if (this->last_clicked == pe && !sd->IsBoolSetting() && !(sd->flags & SF_GUI_DROPDOWN)) {
2704  int64_t value64 = value;
2705  /* Show the correct currency-translated value */
2706  if (sd->flags & SF_GUI_CURRENCY) value64 *= GetCurrency().rate;
2707 
2708  CharSetFilter charset_filter = CS_NUMERAL; //default, only numeric input allowed
2709  if (sd->min < 0) charset_filter = CS_NUMERAL_SIGNED; // special case, also allow '-' sign for negative input
2710 
2711  this->valuewindow_entry = pe;
2712  SetDParam(0, value64);
2713  /* Limit string length to 14 so that MAX_INT32 * max currency rate doesn't exceed MAX_INT64. */
2714  ShowQueryString(STR_JUST_INT, STR_CONFIG_SETTING_QUERY_CAPTION, 15, this, charset_filter, QSF_ENABLE_DEFAULT);
2715  }
2716  this->SetDisplayedHelpText(pe);
2717  }
2718  }
2719 
2720  void OnTimeout() override
2721  {
2722  if (this->clicked_entry != nullptr) { // On timeout, release any depressed buttons
2723  this->clicked_entry->SetButtons(0);
2724  this->clicked_entry = nullptr;
2725  this->SetDirty();
2726  }
2727  }
2728 
2729  void OnQueryTextFinished(std::optional<std::string> str) override
2730  {
2731  /* The user pressed cancel */
2732  if (!str.has_value()) return;
2733 
2734  assert(this->valuewindow_entry != nullptr);
2735  const IntSettingDesc *sd = this->valuewindow_entry->setting;
2736 
2737  int32_t value;
2738  if (!str->empty()) {
2739  long long llvalue = atoll(str->c_str());
2740 
2741  /* Save the correct currency-translated value */
2742  if (sd->flags & SF_GUI_CURRENCY) llvalue /= GetCurrency().rate;
2743 
2744  value = ClampTo<int32_t>(llvalue);
2745  } else if (sd->get_def_cb != nullptr) {
2746  value = sd->get_def_cb();
2747  } else {
2748  value = sd->def;
2749  }
2750 
2751  SetSettingValue(this->valuewindow_entry->setting, value);
2752  this->SetDirty();
2753  }
2754 
2755  void OnDropdownSelect(WidgetID widget, int index) override
2756  {
2757  switch (widget) {
2759  this->filter.mode = (RestrictionMode)index;
2760  if (this->filter.mode == RM_CHANGED_AGAINST_DEFAULT ||
2761  this->filter.mode == RM_CHANGED_AGAINST_NEW) {
2762 
2763  if (!this->manually_changed_folding) {
2764  /* Expand all when selecting 'changes'. Update the filter state first, in case it becomes less restrictive in some cases. */
2765  GetSettingsTree().UpdateFilterState(this->filter, false);
2767  }
2768  } else {
2769  /* Non-'changes' filter. Save as default. */
2771  }
2772  this->InvalidateData();
2773  break;
2774 
2775  case WID_GS_TYPE_DROPDOWN:
2776  this->filter.type = (SettingType)index;
2777  this->InvalidateData();
2778  break;
2779 
2781  /* Deal with drop down boxes on the panel. */
2782  assert(this->valuedropdown_entry != nullptr);
2783  const IntSettingDesc *sd = this->valuedropdown_entry->setting;
2784  assert(sd->flags & SF_GUI_DROPDOWN);
2785 
2786  SetSettingValue(sd, index);
2787  this->SetDirty();
2788  break;
2789  }
2790  }
2791 
2792  void OnDropdownClose(Point pt, WidgetID widget, int index, bool instant_close) override
2793  {
2794  if (widget != WID_GS_SETTING_DROPDOWN) {
2795  /* Normally the default implementation of OnDropdownClose() takes care of
2796  * a few things. We want that behaviour here too, but only for
2797  * "normal" dropdown boxes. The special dropdown boxes added for every
2798  * setting that needs one can't have this call. */
2799  Window::OnDropdownClose(pt, widget, index, instant_close);
2800  } else {
2801  /* We cannot raise the dropdown button just yet. OnClick needs some hint, whether
2802  * the same dropdown button was clicked again, and then not open the dropdown again.
2803  * So, we only remember that it was closed, and process it on the next OnPaint, which is
2804  * after OnClick. */
2805  assert(this->valuedropdown_entry != nullptr);
2806  this->closing_dropdown = true;
2807  this->SetDirty();
2808  }
2809  }
2810 
2811  void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
2812  {
2813  if (!gui_scope) return;
2814 
2815  /* Update which settings are to be visible. */
2816  RestrictionMode min_level = (this->filter.mode <= RM_ALL) ? this->filter.mode : RM_BASIC;
2817  this->filter.min_cat = min_level;
2818  this->filter.type_hides = false;
2819  GetSettingsTree().UpdateFilterState(this->filter, false);
2820 
2821  if (this->filter.string.IsEmpty()) {
2822  this->warn_missing = WHR_NONE;
2823  } else if (min_level < this->filter.min_cat) {
2824  this->warn_missing = this->filter.type_hides ? WHR_CATEGORY_TYPE : WHR_CATEGORY;
2825  } else {
2826  this->warn_missing = this->filter.type_hides ? WHR_TYPE : WHR_NONE;
2827  }
2828  this->vscroll->SetCount(GetSettingsTree().Length() + this->warn_lines);
2829 
2830  if (this->last_clicked != nullptr && !GetSettingsTree().IsVisible(this->last_clicked)) {
2831  this->SetDisplayedHelpText(nullptr);
2832  }
2833 
2834  bool all_folded = true;
2835  bool all_unfolded = true;
2836  GetSettingsTree().GetFoldingState(all_folded, all_unfolded);
2837  this->SetWidgetDisabledState(WID_GS_EXPAND_ALL, all_unfolded);
2838  this->SetWidgetDisabledState(WID_GS_COLLAPSE_ALL, all_folded);
2839  }
2840 
2841  void OnEditboxChanged(WidgetID wid) override
2842  {
2843  if (wid == WID_GS_FILTER) {
2844  this->filter.string.SetFilterTerm(this->filter_editbox.text.buf);
2845  if (!this->filter.string.IsEmpty() && !this->manually_changed_folding) {
2846  /* User never expanded/collapsed single pages and entered a filter term.
2847  * Expand everything, to save weird expand clicks, */
2849  }
2850  this->InvalidateData();
2851  }
2852  }
2853 
2854  void OnResize() override
2855  {
2856  this->vscroll->SetCapacityFromWidget(this, WID_GS_OPTIONSPANEL, WidgetDimensions::scaled.framerect.Vertical());
2857  }
2858 };
2859 
2861 
2862 static constexpr NWidgetPart _nested_settings_selection_widgets[] = {
2864  NWidget(WWT_CLOSEBOX, COLOUR_MAUVE),
2865  NWidget(WWT_CAPTION, COLOUR_MAUVE), SetDataTip(STR_CONFIG_SETTING_TREE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
2866  NWidget(WWT_DEFSIZEBOX, COLOUR_MAUVE),
2867  EndContainer(),
2868  NWidget(WWT_PANEL, COLOUR_MAUVE),
2871  NWidget(WWT_TEXT, COLOUR_MAUVE, WID_GS_RESTRICT_CATEGORY), SetDataTip(STR_CONFIG_SETTING_RESTRICT_CATEGORY, STR_NULL),
2872  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),
2873  EndContainer(),
2875  NWidget(WWT_TEXT, COLOUR_MAUVE, WID_GS_RESTRICT_TYPE), SetDataTip(STR_CONFIG_SETTING_RESTRICT_TYPE, STR_NULL),
2876  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),
2877  EndContainer(),
2879  NWidget(WWT_TEXT, COLOUR_MAUVE), SetFill(0, 1), SetDataTip(STR_CONFIG_SETTING_FILTER_TITLE, STR_NULL),
2880  NWidget(WWT_EDITBOX, COLOUR_MAUVE, WID_GS_FILTER), SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
2881  EndContainer(),
2882  EndContainer(),
2883  EndContainer(),
2886  NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, WID_GS_SCROLLBAR),
2887  EndContainer(),
2888  NWidget(WWT_PANEL, COLOUR_MAUVE),
2889  NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GS_HELP_TEXT), SetMinimalSize(300, 25), SetFill(1, 1), SetResize(1, 0),
2891  EndContainer(),
2893  NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_GS_EXPAND_ALL), SetDataTip(STR_CONFIG_SETTING_EXPAND_ALL, STR_NULL),
2894  NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_GS_COLLAPSE_ALL), SetDataTip(STR_CONFIG_SETTING_COLLAPSE_ALL, STR_NULL),
2895  NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_GS_RESET_ALL), SetDataTip(STR_CONFIG_SETTING_RESET_ALL, STR_NULL),
2896  NWidget(WWT_PANEL, COLOUR_MAUVE), SetFill(1, 0), SetResize(1, 0),
2897  EndContainer(),
2898  NWidget(WWT_RESIZEBOX, COLOUR_MAUVE),
2899  EndContainer(),
2900 };
2901 
2902 static WindowDesc _settings_selection_desc(
2903  WDP_CENTER, "settings", 510, 450,
2905  0,
2906  _nested_settings_selection_widgets
2907 );
2908 
2911 {
2913  new GameSettingsWindow(_settings_selection_desc);
2914 }
2915 
2916 
2926 void DrawArrowButtons(int x, int y, Colours button_colour, uint8_t state, bool clickable_left, bool clickable_right)
2927 {
2928  int colour = GetColourGradient(button_colour, SHADE_DARKER);
2929  Dimension dim = NWidgetScrollbar::GetHorizontalDimension();
2930 
2931  Rect lr = {x, y, x + (int)dim.width - 1, y + (int)dim.height - 1};
2932  Rect rr = {x + (int)dim.width, y, x + (int)dim.width * 2 - 1, y + (int)dim.height - 1};
2933 
2934  DrawFrameRect(lr, button_colour, (state == 1) ? FR_LOWERED : FR_NONE);
2935  DrawFrameRect(rr, button_colour, (state == 2) ? FR_LOWERED : FR_NONE);
2936  DrawSpriteIgnorePadding(SPR_ARROW_LEFT, PAL_NONE, lr, SA_CENTER);
2937  DrawSpriteIgnorePadding(SPR_ARROW_RIGHT, PAL_NONE, rr, SA_CENTER);
2938 
2939  /* Grey out the buttons that aren't clickable */
2940  bool rtl = _current_text_dir == TD_RTL;
2941  if (rtl ? !clickable_right : !clickable_left) {
2943  }
2944  if (rtl ? !clickable_left : !clickable_right) {
2946  }
2947 }
2948 
2957 void DrawDropDownButton(int x, int y, Colours button_colour, bool state, bool clickable)
2958 {
2959  int colour = GetColourGradient(button_colour, SHADE_DARKER);
2960 
2961  Rect r = {x, y, x + SETTING_BUTTON_WIDTH - 1, y + SETTING_BUTTON_HEIGHT - 1};
2962 
2963  DrawFrameRect(r, button_colour, state ? FR_LOWERED : FR_NONE);
2964  DrawSpriteIgnorePadding(SPR_ARROW_DOWN, PAL_NONE, r, SA_CENTER);
2965 
2966  if (!clickable) {
2968  }
2969 }
2970 
2978 void DrawBoolButton(int x, int y, bool state, bool clickable)
2979 {
2980  static const Colours _bool_ctabs[2][2] = {{COLOUR_CREAM, COLOUR_RED}, {COLOUR_DARK_GREEN, COLOUR_GREEN}};
2981 
2982  Rect r = {x, y, x + SETTING_BUTTON_WIDTH - 1, y + SETTING_BUTTON_HEIGHT - 1};
2983  DrawFrameRect(r, _bool_ctabs[state][clickable], state ? FR_LOWERED : FR_NONE);
2984 }
2985 
2987  int query_widget;
2988 
2989  CustomCurrencyWindow(WindowDesc &desc) : Window(desc)
2990  {
2991  this->InitNested();
2992 
2993  SetButtonState();
2994  }
2995 
2996  void SetButtonState()
2997  {
2999  this->SetWidgetDisabledState(WID_CC_RATE_UP, GetCustomCurrency().rate == UINT16_MAX);
3002  }
3003 
3004  void SetStringParameters(WidgetID widget) const override
3005  {
3006  switch (widget) {
3007  case WID_CC_RATE: SetDParam(0, 1); SetDParam(1, 1); break;
3008  case WID_CC_SEPARATOR: SetDParamStr(0, GetCustomCurrency().separator); break;
3009  case WID_CC_PREFIX: SetDParamStr(0, GetCustomCurrency().prefix); break;
3010  case WID_CC_SUFFIX: SetDParamStr(0, GetCustomCurrency().suffix); break;
3011  case WID_CC_YEAR:
3012  SetDParam(0, (GetCustomCurrency().to_euro != CF_NOEURO) ? STR_CURRENCY_SWITCH_TO_EURO : STR_CURRENCY_SWITCH_TO_EURO_NEVER);
3013  SetDParam(1, GetCustomCurrency().to_euro);
3014  break;
3015 
3016  case WID_CC_PREVIEW:
3017  SetDParam(0, 10000);
3018  break;
3019  }
3020  }
3021 
3022  void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
3023  {
3024  switch (widget) {
3025  /* Set the appropriate width for the up/down buttons. */
3026  case WID_CC_RATE_DOWN:
3027  case WID_CC_RATE_UP:
3028  case WID_CC_YEAR_DOWN:
3029  case WID_CC_YEAR_UP:
3030  size = maxdim(size, {(uint)SETTING_BUTTON_WIDTH / 2, (uint)SETTING_BUTTON_HEIGHT});
3031  break;
3032 
3033  /* Set the appropriate width for the edit buttons. */
3034  case WID_CC_SEPARATOR_EDIT:
3035  case WID_CC_PREFIX_EDIT:
3036  case WID_CC_SUFFIX_EDIT:
3037  size = maxdim(size, {(uint)SETTING_BUTTON_WIDTH, (uint)SETTING_BUTTON_HEIGHT});
3038  break;
3039 
3040  /* Make sure the window is wide enough for the widest exchange rate */
3041  case WID_CC_RATE:
3042  SetDParam(0, 1);
3043  SetDParam(1, INT32_MAX);
3044  size = GetStringBoundingBox(STR_CURRENCY_EXCHANGE_RATE);
3045  break;
3046  }
3047  }
3048 
3049  void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
3050  {
3051  int line = 0;
3052  int len = 0;
3053  StringID str = 0;
3054  CharSetFilter afilter = CS_ALPHANUMERAL;
3055 
3056  switch (widget) {
3057  case WID_CC_RATE_DOWN:
3058  if (GetCustomCurrency().rate > 1) GetCustomCurrency().rate--;
3059  if (GetCustomCurrency().rate == 1) this->DisableWidget(WID_CC_RATE_DOWN);
3061  break;
3062 
3063  case WID_CC_RATE_UP:
3064  if (GetCustomCurrency().rate < UINT16_MAX) GetCustomCurrency().rate++;
3065  if (GetCustomCurrency().rate == UINT16_MAX) this->DisableWidget(WID_CC_RATE_UP);
3067  break;
3068 
3069  case WID_CC_RATE:
3070  SetDParam(0, GetCustomCurrency().rate);
3071  str = STR_JUST_INT;
3072  len = 5;
3073  line = WID_CC_RATE;
3074  afilter = CS_NUMERAL;
3075  break;
3076 
3077  case WID_CC_SEPARATOR_EDIT:
3078  case WID_CC_SEPARATOR:
3079  SetDParamStr(0, GetCustomCurrency().separator);
3080  str = STR_JUST_RAW_STRING;
3081  len = 7;
3082  line = WID_CC_SEPARATOR;
3083  break;
3084 
3085  case WID_CC_PREFIX_EDIT:
3086  case WID_CC_PREFIX:
3087  SetDParamStr(0, GetCustomCurrency().prefix);
3088  str = STR_JUST_RAW_STRING;
3089  len = 15;
3090  line = WID_CC_PREFIX;
3091  break;
3092 
3093  case WID_CC_SUFFIX_EDIT:
3094  case WID_CC_SUFFIX:
3095  SetDParamStr(0, GetCustomCurrency().suffix);
3096  str = STR_JUST_RAW_STRING;
3097  len = 15;
3098  line = WID_CC_SUFFIX;
3099  break;
3100 
3101  case WID_CC_YEAR_DOWN:
3105  break;
3106 
3107  case WID_CC_YEAR_UP:
3111  break;
3112 
3113  case WID_CC_YEAR:
3114  SetDParam(0, GetCustomCurrency().to_euro);
3115  str = STR_JUST_INT;
3116  len = 7;
3117  line = WID_CC_YEAR;
3118  afilter = CS_NUMERAL;
3119  break;
3120  }
3121 
3122  if (len != 0) {
3123  this->query_widget = line;
3124  ShowQueryString(str, STR_CURRENCY_CHANGE_PARAMETER, len + 1, this, afilter, QSF_NONE);
3125  }
3126 
3127  this->SetTimeout();
3128  this->SetDirty();
3129  }
3130 
3131  void OnQueryTextFinished(std::optional<std::string> str) override
3132  {
3133  if (!str.has_value()) return;
3134 
3135  switch (this->query_widget) {
3136  case WID_CC_RATE:
3137  GetCustomCurrency().rate = Clamp(atoi(str->c_str()), 1, UINT16_MAX);
3138  break;
3139 
3140  case WID_CC_SEPARATOR: // Thousands separator
3141  GetCustomCurrency().separator = std::move(*str);
3142  break;
3143 
3144  case WID_CC_PREFIX:
3145  GetCustomCurrency().prefix = std::move(*str);
3146  break;
3147 
3148  case WID_CC_SUFFIX:
3149  GetCustomCurrency().suffix = std::move(*str);
3150  break;
3151 
3152  case WID_CC_YEAR: { // Year to switch to euro
3153  TimerGameCalendar::Year val = atoi(str->c_str());
3154 
3156  break;
3157  }
3158  }
3160  SetButtonState();
3161  }
3162 
3163  void OnTimeout() override
3164  {
3165  this->SetDirty();
3166  }
3167 };
3168 
3169 static constexpr NWidgetPart _nested_cust_currency_widgets[] = {
3171  NWidget(WWT_CLOSEBOX, COLOUR_GREY),
3172  NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_CURRENCY_WINDOW, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
3173  EndContainer(),
3174  NWidget(WWT_PANEL, COLOUR_GREY),
3179  NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_CC_RATE_DOWN), SetDataTip(AWV_DECREASE, STR_CURRENCY_DECREASE_EXCHANGE_RATE_TOOLTIP),
3180  NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_CC_RATE_UP), SetDataTip(AWV_INCREASE, STR_CURRENCY_INCREASE_EXCHANGE_RATE_TOOLTIP),
3181  EndContainer(),
3182  NWidget(WWT_TEXT, COLOUR_BLUE, WID_CC_RATE), SetDataTip(STR_CURRENCY_EXCHANGE_RATE, STR_CURRENCY_SET_EXCHANGE_RATE_TOOLTIP), SetFill(1, 0),
3183  EndContainer(),
3185  NWidget(WWT_PUSHBTN, COLOUR_DARK_BLUE, WID_CC_SEPARATOR_EDIT), SetDataTip(0x0, STR_CURRENCY_SET_CUSTOM_CURRENCY_SEPARATOR_TOOLTIP), SetFill(0, 1),
3186  NWidget(WWT_TEXT, COLOUR_BLUE, WID_CC_SEPARATOR), SetDataTip(STR_CURRENCY_SEPARATOR, STR_CURRENCY_SET_CUSTOM_CURRENCY_SEPARATOR_TOOLTIP), SetFill(1, 0),
3187  EndContainer(),
3189  NWidget(WWT_PUSHBTN, COLOUR_DARK_BLUE, WID_CC_PREFIX_EDIT), SetDataTip(0x0, STR_CURRENCY_SET_CUSTOM_CURRENCY_PREFIX_TOOLTIP), SetFill(0, 1),
3190  NWidget(WWT_TEXT, COLOUR_BLUE, WID_CC_PREFIX), SetDataTip(STR_CURRENCY_PREFIX, STR_CURRENCY_SET_CUSTOM_CURRENCY_PREFIX_TOOLTIP), SetFill(1, 0),
3191  EndContainer(),
3193  NWidget(WWT_PUSHBTN, COLOUR_DARK_BLUE, WID_CC_SUFFIX_EDIT), SetDataTip(0x0, STR_CURRENCY_SET_CUSTOM_CURRENCY_SUFFIX_TOOLTIP), SetFill(0, 1),
3194  NWidget(WWT_TEXT, COLOUR_BLUE, WID_CC_SUFFIX), SetDataTip(STR_CURRENCY_SUFFIX, STR_CURRENCY_SET_CUSTOM_CURRENCY_SUFFIX_TOOLTIP), SetFill(1, 0),
3195  EndContainer(),
3198  NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_CC_YEAR_DOWN), SetDataTip(AWV_DECREASE, STR_CURRENCY_DECREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP),
3199  NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_CC_YEAR_UP), SetDataTip(AWV_INCREASE, STR_CURRENCY_INCREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP),
3200  EndContainer(),
3201  NWidget(WWT_TEXT, COLOUR_BLUE, WID_CC_YEAR), SetDataTip(STR_JUST_STRING1, STR_CURRENCY_SET_CUSTOM_CURRENCY_TO_EURO_TOOLTIP), SetFill(1, 0),
3202  EndContainer(),
3203  EndContainer(),
3204  NWidget(WWT_LABEL, COLOUR_BLUE, WID_CC_PREVIEW),
3205  SetDataTip(STR_CURRENCY_PREVIEW, STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP),
3206  EndContainer(),
3207  EndContainer(),
3208 };
3209 
3210 static WindowDesc _cust_currency_desc(
3211  WDP_CENTER, nullptr, 0, 0,
3213  0,
3214  _nested_cust_currency_widgets
3215 );
3216 
3218 static void ShowCustCurrency()
3219 {
3221  new CustomCurrencyWindow(_cust_currency_desc);
3222 }
SZSP_NONE
@ SZSP_NONE
Display plane with zero size in both directions (none filling and resizing).
Definition: widget_type.h:485
WID_CC_YEAR_DOWN
@ WID_CC_YEAR_DOWN
Down button.
Definition: settings_widget.h:94
Window::timeout_timer
uint8_t timeout_timer
Timer value of the WF_TIMEOUT for flags.
Definition: window_gui.h:309
network_content.h
DrawArrowButtons
void DrawArrowButtons(int x, int y, Colours button_colour, uint8_t state, bool clickable_left, bool clickable_right)
Draw [<][>] boxes.
Definition: settings_gui.cpp:2926
WC_CUSTOM_CURRENCY
@ WC_CUSTOM_CURRENCY
Custom currency; Window numbers:
Definition: window_type.h:624
NWidgetResizeBase
Base class for a resizable nested widget.
Definition: widget_type.h:305
SEF_RIGHT_DEPRESSED
@ SEF_RIGHT_DEPRESSED
Of a numeric setting entry, the right button is depressed.
Definition: settings_gui.cpp:1213
SetFill
constexpr NWidgetPart SetFill(uint16_t fill_x, uint16_t fill_y)
Widget part function for setting filling.
Definition: widget_type.h:1183
_autosave_dropdown_to_minutes
static const uint32_t _autosave_dropdown_to_minutes[]
Available settings for autosave intervals.
Definition: settings_gui.cpp:71
GetColourGradient
uint8_t GetColourGradient(Colours colour, ColourShade shade)
Get colour gradient palette index.
Definition: palette.cpp:314
WID_CC_PREVIEW
@ WID_CC_PREVIEW
Preview.
Definition: settings_widget.h:97
NWidgetContainer::children
std::vector< std::unique_ptr< NWidgetBase > > children
Child widgets in contaier.
Definition: widget_type.h:478
Window::SetTimeout
void SetTimeout()
Set the timeout flag of the window and initiate the timer.
Definition: window_gui.h:364
CustomCurrencyWindow::OnTimeout
void OnTimeout() override
Called when this window's timeout has been reached.
Definition: settings_gui.cpp:3163
CloseWindowByClass
void CloseWindowByClass(WindowClass cls, int data)
Close all windows of a given class.
Definition: window.cpp:1152
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:1744
sound_func.h
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:78
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:1212
BaseSetTextfileWindow::name
const std::string name
Name of the content.
Definition: settings_gui.cpp:97
querystring_gui.h
GetCurrentLanguageIsoCode
const char * GetCurrentLanguageIsoCode()
Get the ISO language code of the currently loaded language.
Definition: strings.cpp:2140
SEF_BUTTONS_MASK
@ SEF_BUTTONS_MASK
Bit-mask for button flags.
Definition: settings_gui.cpp:1214
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:1223
WID_TF_CAPTION
@ WID_TF_CAPTION
The caption of the window.
Definition: misc_widget.h:50
WID_GO_BASE_SFX_OPEN_URL
@ WID_GO_BASE_SFX_OPEN_URL
Open base SFX URL.
Definition: settings_widget.h:41
WID_GS_COLLAPSE_ALL
@ WID_GS_COLLAPSE_ALL
Collapse all button.
Definition: settings_widget.h:73
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
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_common_type.h:97
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:1616
GameSettingsWindow
Window to edit settings of the game.
Definition: settings_gui.cpp:2321
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:41
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:1840
WID_CC_RATE_UP
@ WID_CC_RATE_UP
Up button.
Definition: settings_widget.h:86
BaseSettingEntry::Init
virtual void Init(uint8_t level=0)
Initialization of a setting entry.
Definition: settings_gui.cpp:1361
company_base.h
SettingsPage::Length
uint Length() const override
Return number of rows needed to display the (filtered) entry.
Definition: settings_gui.cpp:1892
WID_GS_FILTER
@ WID_GS_FILTER
Text filter.
Definition: settings_widget.h:68
GameSettingsWindow::settings_ptr
static GameSettings * settings_ptr
Pointer to the game settings being displayed and modified.
Definition: settings_gui.cpp:2322
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:287
IntSettingDesc::cat
SettingCategory cat
assigned categories of the setting
Definition: settings_internal.h:226
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:2368
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:2811
ChangeSoundSet
void ChangeSoundSet(int index)
Change the configured sound set and reset sounds.
Definition: sound.cpp:241
WID_GO_SOCIAL_PLUGIN_PLATFORM
@ WID_GO_SOCIAL_PLUGIN_PLATFORM
Platform of the social plugin.
Definition: settings_widget.h:62
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:1197
SettingFilter::type
SettingType type
Filter based on type.
Definition: settings_gui.cpp:1237
WWT_CAPTION
@ WWT_CAPTION
Window caption (window title between closebox and stickybox)
Definition: widget_type.h:63
GetCustomCurrency
CurrencySpec & GetCustomCurrency()
Get the custom currency.
Definition: currency.h:108
Window::SetWidgetDirty
void SetWidgetDirty(WidgetID widget_index) const
Invalidate a widget, i.e.
Definition: window.cpp:551
BASESET_DIR
@ BASESET_DIR
Subdirectory for all base data (base sets, intro game)
Definition: fileio_type.h:123
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:1373
SetAlignment
constexpr NWidgetPart SetAlignment(StringAlignment align)
Widget part function for setting the alignment of text/images.
Definition: widget_type.h:1172
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:1282
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:1140
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:50
SettingDesc::GetType
SettingType GetType() const
Return the type of the setting.
Definition: settings.cpp:900
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:74
WID_GO_SURVEY_SEL
@ WID_GO_SURVEY_SEL
Selection to hide survey if no JSON library is compiled in.
Definition: settings_widget.h:56
SettingEntry::Init
void Init(uint8_t level=0) override
Initialization of a setting entry.
Definition: settings_gui.cpp:1471
SettingDesc::IsEditable
bool IsEditable(bool do_command=false) const
Check whether the setting is editable in the current gamemode.
Definition: settings.cpp:883
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:1754
WID_CC_RATE_DOWN
@ WID_CC_RATE_DOWN
Down button.
Definition: settings_widget.h:85
ShowNetworkContentListWindow
void ShowNetworkContentListWindow(ContentVector *cv=nullptr, ContentType type1=CONTENT_TYPE_END, ContentType type2=CONTENT_TYPE_END)
Show the content list window with a given set of content.
Definition: network_content_gui.cpp:1129
GameSettingsWindow::filter_editbox
QueryString filter_editbox
Filter editbox;.
Definition: settings_gui.cpp:2331
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:72
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:1047
BaseSettingEntry::SetLastField
void SetLastField(bool last_field)
Set whether this is the last visible entry of the parent node.
Definition: settings_gui.cpp:1257
Window::EnableWidget
void EnableWidget(WidgetID widget_index)
Sets a widget to Enabled.
Definition: window_gui.h:409
WID_GS_RESTRICT_DROPDOWN
@ WID_GS_RESTRICT_DROPDOWN
The drop down box to restrict the list of settings.
Definition: settings_widget.h:77
EndContainer
constexpr NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
Definition: widget_type.h:1193
BaseSetTextfileWindow
Window for displaying the textfile of a BaseSet.
Definition: settings_gui.cpp:96
WID_GO_SOCIAL_PLUGIN_TITLE
@ WID_GO_SOCIAL_PLUGIN_TITLE
Title of the frame of the social plugin.
Definition: settings_widget.h:61
_ctrl_pressed
bool _ctrl_pressed
Is Ctrl pressed?
Definition: gfx.cpp:38
FILLRECT_CHECKER
@ FILLRECT_CHECKER
Draw only every second pixel, used for greying-out.
Definition: gfx_type.h:301
WID_GO_SURVEY_PREVIEW_BUTTON
@ WID_GO_SURVEY_PREVIEW_BUTTON
Button to open a preview window with the survey results.
Definition: settings_widget.h:59
WID_GS_SCROLLBAR
@ WID_GS_SCROLLBAR
Scrollbar.
Definition: settings_widget.h:70
_currency_specs
std::array< CurrencySpec, CURRENCY_END > _currency_specs
Array of currencies used by the system.
Definition: currency.cpp:77
SettingFilter::string
StringFilter string
Filter string.
Definition: settings_gui.cpp:1233
GameOptionsWindow
Definition: settings_gui.cpp:356
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:2394
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:47
base_media_base.h
NWidgetResizeBase::UpdateVerticalSize
bool UpdateVerticalSize(uint min_y)
Set absolute (post-scaling) minimal size of the widget.
Definition: widget.cpp:1092
SettingsContainer::entries
EntryVector entries
Settings on this page.
Definition: settings_gui.cpp:1304
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:56
GameSettingsWindow::last_clicked
SettingEntry * last_clicked
If non-nullptr, pointer to the last clicked setting.
Definition: settings_gui.cpp:2326
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:1906
WID_GO_BASE_GRF_TEXTFILE
@ WID_GO_BASE_GRF_TEXTFILE
Open base GRF readme, changelog (+1) or license (+2).
Definition: settings_widget.h:35
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:116
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
IntSettingDesc::get_def_cb
GetDefaultValueCallback * get_def_cb
Callback to set the correct default value.
Definition: settings_internal.h:232
settings_internal.h
MusicSettings::effect_vol
uint8_t effect_vol
The requested effects volume.
Definition: settings_type.h:259
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:347
SEF_FILTERED
@ SEF_FILTERED
Entry is hidden by the string filter.
Definition: settings_gui.cpp:1217
NWidgetFunction
constexpr NWidgetPart NWidgetFunction(NWidgetFunctionType *func_ptr)
Obtain a nested widget (sub)tree from an external source.
Definition: widget_type.h:1332
WC_MUSIC_WINDOW
@ WC_MUSIC_WINDOW
Music window; Window numbers:
Definition: window_type.h:601
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:1515
SettingsPage::SettingsPage
SettingsPage(StringID title)
Constructor for a sub-page in the 'advanced settings' window.
Definition: settings_gui.cpp:1793
WID_GO_VIDEO_DRIVER_INFO
@ WID_GO_VIDEO_DRIVER_INFO
Label showing details about the current video driver.
Definition: settings_widget.h:55
Scrollbar
Scrollbar data structure.
Definition: widget_type.h:696
Window::GetScrollbar
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
Definition: window.cpp:314
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:1330
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:1694
Rect::WithHeight
Rect WithHeight(int height, bool end=false) const
Copy Rect and set its height.
Definition: geometry_type.hpp:211
CustomCurrencyWindow
Definition: settings_gui.cpp:2986
NWidgetPart
Partial widget specification to allow NWidgets to be written nested.
Definition: widget_type.h:1077
textfile_gui.h
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:224
WID_GO_BASE_MUSIC_DESCRIPTION
@ WID_GO_BASE_MUSIC_DESCRIPTION
Description of selected base music set.
Definition: settings_widget.h:51
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:2720
_gui_scale
int _gui_scale
GUI scale, 100 is 100%.
Definition: gfx.cpp:63
GetStringLineCount
int GetStringLineCount(StringID str, int maxw)
Calculates number of lines of string.
Definition: gfx.cpp:728
textbuf_gui.h
Textbuf::buf
char *const buf
buffer in which text is saved
Definition: textbuf_type.h:32
GetCurrency
const CurrencySpec & GetCurrency()
Get the currently selected currency.
Definition: currency.h:117
MakeNWidgetSocialPlugins
std::unique_ptr< NWidgetBase > MakeNWidgetSocialPlugins()
Construct nested container widget for managing the list of social plugins.
Definition: settings_gui.cpp:351
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:1818
Scrollbar::GetCount
size_type GetCount() const
Gets the number of elements in the list.
Definition: widget_type.h:724
WID_GO_BASE_GRF_OPEN_URL
@ WID_GO_BASE_GRF_OPEN_URL
Open base GRF URL.
Definition: settings_widget.h:34
WindowDesc
High level window description.
Definition: window_gui.h:162
GameSettingsWindow::warn_missing
WarnHiddenResult warn_missing
Whether and how to warn about missing search results.
Definition: settings_gui.cpp:2333
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:1793
WID_GO_BASE_SFX_DESCRIPTION
@ WID_GO_BASE_SFX_DESCRIPTION
Description of selected base SFX.
Definition: settings_widget.h:43
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:64
GUISettings::refresh_rate
uint16_t refresh_rate
How often we refresh the screen (time between draw-ticks).
Definition: settings_type.h:209
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:1608
SettingsPage::title
StringID title
Title of the sub-page.
Definition: settings_gui.cpp:1331
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:1234
NC_EQUALSIZE
@ NC_EQUALSIZE
Value of the NCB_EQUALSIZE flag.
Definition: widget_type.h:526
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:1230
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:69
SettingsPage::UpdateFilterState
bool UpdateFilterState(SettingFilter &filter, bool force_visible) override
Update the filter state.
Definition: settings_gui.cpp:1859
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:1128
DrawDropDownButton
void DrawDropDownButton(int x, int y, Colours button_colour, bool state, bool clickable)
Draw a dropdown button.
Definition: settings_gui.cpp:2957
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:113
SettingsPage::ResetAll
void ResetAll() override
Resets all settings to their default values.
Definition: settings_gui.cpp:1810
Window::resize
ResizeInfo resize
Resize information.
Definition: window_gui.h:317
GameSettingsWindow::warn_lines
int warn_lines
Number of lines used for warning about missing search results.
Definition: settings_gui.cpp:2334
ResetAllSettingsConfirmationCallback
static void ResetAllSettingsConfirmationCallback(Window *w, bool confirmed)
Callback function for the reset all settings button.
Definition: settings_gui.cpp:2311
VideoDriver::GetListOfMonitorRefreshRates
virtual std::vector< int > GetListOfMonitorRefreshRates()
Get a list of refresh rates of each available monitor.
Definition: video_driver.hpp:163
WID_GO_BASE_SFX_CONTENT_DOWNLOAD
@ WID_GO_BASE_SFX_CONTENT_DOWNLOAD
'Get Content' button for base SFX.
Definition: settings_widget.h:38
WID_GO_BASE_MUSIC_DROPDOWN
@ WID_GO_BASE_MUSIC_DROPDOWN
Use to select a base music set.
Definition: settings_widget.h:44
SETTING_HEIGHT
static int SETTING_HEIGHT
Height of a single setting in the tree view in pixels.
Definition: settings_gui.cpp:1205
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:209
RestrictionMode
RestrictionMode
How the list of advanced settings is filtered.
Definition: settings_gui.cpp:1221
SettingEntry::UpdateFilterState
bool UpdateFilterState(SettingFilter &filter, bool force_visible) override
Update the filter state.
Definition: settings_gui.cpp:1556
Window::InitNested
void InitNested(WindowNumber number=0)
Perform complete initialization of the Window with nested widgets, to allow use.
Definition: window.cpp:1746
SetScrollbar
constexpr NWidgetPart SetScrollbar(WidgetID index)
Attach a scrollbar to a widget.
Definition: widget_type.h:1286
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:2324
ReInitAllWindows
void ReInitAllWindows(bool zoom_changed)
Re-initialize all windows.
Definition: window.cpp:3324
CurrencySpec::suffix
std::string suffix
Suffix to apply when formatting money in this currency.
Definition: currency.h:80
WHR_TYPE
@ WHR_TYPE
Type setting filtered matches away.
Definition: settings_gui.cpp:2302
Window::height
int height
Height of the window (number of pixels down in y direction)
Definition: window_gui.h:315
WF_CENTERED
@ WF_CENTERED
Window is centered and shall stay centered after ReInit.
Definition: window_gui.h:241
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:940
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:830
FS_SMALL
@ FS_SMALL
Index of the small font in the font tables.
Definition: gfx_type.h:210
SettingsContainer::ResetAll
void ResetAll()
Resets all settings to their default values.
Definition: settings_gui.cpp:1653
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:75
BaseSettingEntry
Data structure describing a single setting in a tab.
Definition: settings_gui.cpp:1241
NWidgetContainer::FillWidgetLookup
void FillWidgetLookup(WidgetLookup &widget_lookup) override
Definition: widget.cpp:1204
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:970
WWT_PUSHTXTBTN
@ WWT_PUSHTXTBTN
Normal push-button (no toggle button) with text caption.
Definition: widget_type.h:114
InitFontCache
void InitFontCache(bool monospace)
(Re)initialize the font cache related things, i.e.
Definition: fontcache.cpp:218
WID_GO_SOCIAL_PLUGINS
@ WID_GO_SOCIAL_PLUGINS
Main widget handling the social plugins.
Definition: settings_widget.h:60
IntSettingDesc::def
int32_t def
default value given when none is present
Definition: settings_internal.h:219
NWidgetBase
Baseclass for nested widgets.
Definition: widget_type.h:146
NWidgetSocialPlugins::FillWidgetLookup
void FillWidgetLookup(WidgetLookup &widget_lookup) override
Definition: settings_gui.cpp:218
RM_END
@ RM_END
End for iteration.
Definition: settings_gui.cpp:1227
FontCacheSettings::prefer_sprite
bool prefer_sprite
Whether to prefer the built-in sprite font over resizable fonts.
Definition: fontcache.h:205
WID_GO_TEXT_MUSIC_VOLUME
@ WID_GO_TEXT_MUSIC_VOLUME
Music volume label.
Definition: settings_widget.h:46
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:386
SettingFilter::mode
RestrictionMode mode
Filter based on category.
Definition: settings_gui.cpp:1236
WID_GO_TAB_GENERAL
@ WID_GO_TAB_GENERAL
General tab.
Definition: settings_widget.h:15
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:1882
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:96
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:952
WID_GO_BASE_SFX_VOLUME
@ WID_GO_BASE_SFX_VOLUME
Change sound effects volume.
Definition: settings_widget.h:40
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:2792
IntSettingDesc::min
int32_t min
minimum values
Definition: settings_internal.h:220
SettingEntry::name
const char * name
Name of the setting.
Definition: settings_gui.cpp:1281
TextfileWindow::LoadTextfile
virtual void LoadTextfile(const std::string &textfile, Subdirectory dir)
Loads the textfile text from file and setup lines.
Definition: textfile_gui.cpp:734
WL_INFO
@ WL_INFO
Used for DoCommand-like (and some non-fatal AI GUI) errors/information.
Definition: error.h:24
Scrollbar::GetScrolledRowFromWidget
size_type GetScrolledRowFromWidget(int clickpos, const Window *const w, WidgetID widget, int padding=0, int line_height=-1) const
Compute the row of a scrolled widget that a user clicked in.
Definition: widget.cpp:2320
NWidget
constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx=-1)
Widget part function for starting a new 'real' widget.
Definition: widget_type.h:1311
WID_GO_SOCIAL_PLUGIN_STATE
@ WID_GO_SOCIAL_PLUGIN_STATE
State of the social plugin.
Definition: settings_widget.h:63
_local_company
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:52
_current_language
const LanguageMetadata * _current_language
The currently loaded language.
Definition: strings.cpp:54
CurrencySpec::code
std::string code
3 letter untranslated code to identify the currency.
Definition: currency.h:81
SEF_LAST_FIELD
@ SEF_LAST_FIELD
This entry is the last one in a (sub-)page.
Definition: settings_gui.cpp:1216
WID_GO_TEXT_SFX_VOLUME
@ WID_GO_TEXT_SFX_VOLUME
Sound effects volume label.
Definition: settings_widget.h:39
GetMaskOfAllowedCurrencies
uint64_t GetMaskOfAllowedCurrencies()
get a mask of the allowed currencies depending on the year
Definition: currency.cpp:125
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:1079
RM_ALL
@ RM_ALL
List all settings regardless of the default/newgame/... values.
Definition: settings_gui.cpp:1224
Window::LowerWidget
void LowerWidget(WidgetID widget_index)
Marks a widget as lowered.
Definition: window_gui.h:469
music_driver.hpp
lengthof
#define lengthof(array)
Return the length of an fixed size array.
Definition: stdafx.h:280
Window::flags
WindowFlags flags
Window flags.
Definition: window_gui.h:303
_resolutions
std::vector< Dimension > _resolutions
List of resolutions.
Definition: driver.cpp:25
WF_TIMEOUT
@ WF_TIMEOUT
Window timeout counter.
Definition: window_gui.h:231
NWidgetVertical::SetupSmallestSize
void SetupSmallestSize(Window *w) override
Definition: widget.cpp:1599
GetStringHeight
int GetStringHeight(std::string_view str, int maxw, FontSize fontsize)
Calculates height of string (in pixels).
Definition: gfx.cpp:704
Window::Window
Window(WindowDesc &desc)
Empty constructor, initialization has been moved to InitNested() called from the constructor of the d...
Definition: window.cpp:1756
WID_GO_VIDEO_ACCEL_BUTTON
@ WID_GO_VIDEO_ACCEL_BUTTON
Toggle for video acceleration.
Definition: settings_widget.h:52
GameSettings
All settings together for the game.
Definition: settings_type.h:592
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:1332
CurrencySpec::rate
uint16_t rate
The conversion rate compared to the base currency.
Definition: currency.h:76
ChangeAutosaveFrequency
void ChangeAutosaveFrequency(bool reset)
Reset the interval of the autosave.
Definition: openttd.cpp:1318
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:988
SettingEntry::SetButtons
void SetButtons(uint8_t new_val)
Set the button-depressed flags (SEF_LEFT_DEPRESSED and SEF_RIGHT_DEPRESSED) to a specified value.
Definition: settings_gui.cpp:1488
GameOptionsWindow::OnMouseLoop
void OnMouseLoop() override
Called for every mouse loop run, which is at least once per (game) tick.
Definition: settings_gui.cpp:891
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:2327
Point
Coordinates of a point in 2D.
Definition: geometry_type.hpp:21
NWidgetSocialPlugins
Definition: settings_gui.cpp:199
error.h
ClickSliderWidget
bool ClickSliderWidget(Rect r, Point pt, int min_value, int max_value, int nmarks, int &value)
Handle click on a slider widget to change the value.
Definition: slider.cpp:91
WID_GO_BASE_GRF_DESCRIPTION
@ WID_GO_BASE_GRF_DESCRIPTION
Description of selected base GRF.
Definition: settings_widget.h:36
CheckBlitter
void CheckBlitter()
Check whether we still use the right blitter, or use another (better) one.
Definition: gfxinit.cpp:316
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:1222
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:146
WHR_CATEGORY
@ WHR_CATEGORY
Category setting filtered matches away.
Definition: settings_gui.cpp:2301
WID_CC_SUFFIX
@ WID_CC_SUFFIX
Current suffix.
Definition: settings_widget.h:93
MakeNWidgets
std::unique_ptr< NWidgetBase > MakeNWidgets(std::span< const NWidgetPart > nwid_parts, std::unique_ptr< NWidgetBase > &&container)
Construct a nested widget tree from an array of parts.
Definition: widget.cpp:3210
Scrollbar::GetCapacity
size_type GetCapacity() const
Gets the number of visible elements of the scrollbar.
Definition: widget_type.h:733
SETTING_BUTTON_WIDTH
#define SETTING_BUTTON_WIDTH
Width of setting buttons.
Definition: settings_gui.h:17
stdafx.h
SettingFilter::type_hides
bool type_hides
Whether the type hides filtered strings.
Definition: settings_gui.cpp:1235
Window::SetFocusedWidget
bool SetFocusedWidget(WidgetID widget_index)
Set focus within this window to the given widget.
Definition: window.cpp:486
WID_GS_SETTING_DROPDOWN
@ WID_GS_SETTING_DROPDOWN
Dynamically created dropdown for changing setting value.
Definition: settings_widget.h:80
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:114
ShowCustCurrency
static void ShowCustCurrency()
Open custom currency window.
Definition: settings_gui.cpp:3218
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:450
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:1778
CurrencySpec
Specification of a currency.
Definition: currency.h:75
WarnHiddenResult
WarnHiddenResult
Warnings about hidden search results.
Definition: settings_gui.cpp:2299
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:3148
VideoDriver::GetInstance
static VideoDriver * GetInstance()
Get the currently active instance of the video driver.
Definition: video_driver.hpp:201
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
SettingsContainer::Init
void Init(uint8_t level=0)
Initialization of an entire setting page.
Definition: settings_gui.cpp:1645
WHR_CATEGORY_TYPE
@ WHR_CATEGORY_TYPE
Both category and type settings filtered matches away.
Definition: settings_gui.cpp:2303
Window::SetWidgetLoweredState
void SetWidgetLoweredState(WidgetID widget_index, bool lowered_stat)
Sets the lowered/raised status of a widget.
Definition: window_gui.h:450
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:87
WID_GO_RESOLUTION_DROPDOWN
@ WID_GO_RESOLUTION_DROPDOWN
Dropdown for the resolution.
Definition: settings_widget.h:24
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:390
GetSpriteSize
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition: gfx.cpp:922
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
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:237
TFT_LICENSE
@ TFT_LICENSE
Content license.
Definition: textfile_type.h:19
_switch_mode
SwitchMode _switch_mode
The next mainloop command.
Definition: gfx.cpp:49
GameSettingsWindow::OnResize
void OnResize() override
Called after the window got resized.
Definition: settings_gui.cpp:2854
WWT_PUSHIMGBTN
@ WWT_PUSHIMGBTN
Normal push-button (no toggle button) with image caption.
Definition: widget_type.h:115
WID_GO_VIDEO_VSYNC_BUTTON
@ WID_GO_VIDEO_VSYNC_BUTTON
Toggle for video vsync.
Definition: settings_widget.h:53
WID_GO_SURVEY_PARTICIPATE_BUTTON
@ WID_GO_SURVEY_PARTICIPATE_BUTTON
Toggle for participating in the automated survey.
Definition: settings_widget.h:57
Window::querystrings
std::map< WidgetID, QueryString * > querystrings
QueryString associated to WWT_EDITBOX widgets.
Definition: window_gui.h:323
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:774
CONTENT_TYPE_BASE_GRAPHICS
@ CONTENT_TYPE_BASE_GRAPHICS
The content consists of base graphics.
Definition: tcp_content_type.h:20
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:618
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:1723
strings_func.h
WID_GO_BASE_SFX_DROPDOWN
@ WID_GO_BASE_SFX_DROPDOWN
Use to select a base SFX.
Definition: settings_widget.h:37
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:441
main
int CDECL main(int argc, char *argv[])
And the main program (what else?)
Definition: settingsgen.cpp:422
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:76
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:222
WidgetLookup
std::map< WidgetID, class NWidgetBase * > WidgetLookup
Lookup between widget IDs and NWidget objects.
Definition: widget_type.h:138
BaseSettingEntry::FindEntry
virtual BaseSettingEntry * FindEntry(uint row, uint *cur_row)
Find setting entry at row row_num.
Definition: settings_gui.cpp:1384
SettingsContainer::UnFoldAll
void UnFoldAll()
Recursively open all folds of sub-pages.
Definition: settings_gui.cpp:1669
Window::DisableWidget
void DisableWidget(WidgetID widget_index)
Sets a widget to disabled.
Definition: window_gui.h:400
Window::CloseChildWindows
void CloseChildWindows(WindowClass wc=WC_INVALID) const
Close all children a window might have in a head-recursive manner.
Definition: window.cpp:1035
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:1262
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:1713
SettingsContainer::Length
uint Length() const
Return number of rows needed to display the whole page.
Definition: settings_gui.cpp:1722
video_driver.hpp
BaseSettingEntry::level
uint8_t level
Nesting level of this setting entry.
Definition: settings_gui.cpp:1243
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:1225
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:168
geometry_func.hpp
WID_GO_BASE_MUSIC_JUKEBOX
@ WID_GO_BASE_MUSIC_JUKEBOX
Open the jukebox.
Definition: settings_widget.h:48
IntSettingDesc::max
uint32_t max
maximum values
Definition: settings_internal.h:221
GameSettingsWindow::OnPaint
void OnPaint() override
The window must be repainted.
Definition: settings_gui.cpp:2408
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:561
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:238
WID_GS_RESET_ALL
@ WID_GS_RESET_ALL
Reset all button.
Definition: settings_widget.h:74
Scrollbar::SetCount
void SetCount(size_t num)
Sets the number of elements in the list.
Definition: widget_type.h:782
IntSettingDesc::IsBoolSetting
virtual bool IsBoolSetting() const
Check whether this setting is a boolean type setting.
Definition: settings_internal.h:242
NWidgetVertical
Vertical container.
Definition: widget_type.h:583
SettingsContainer::FindEntry
BaseSettingEntry * FindEntry(uint row, uint *cur_row)
Find the setting entry at row number row_num.
Definition: settings_gui.cpp:1737
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:329
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:92
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:344
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:1930
WID_CC_SEPARATOR_EDIT
@ WID_CC_SEPARATOR_EDIT
Separator edit button.
Definition: settings_widget.h:88
Window::FinishInitNested
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition: window.cpp:1733
IntSettingDesc::SetValueDParams
void SetValueDParams(uint first_param, int32_t value) const
Set the DParams for drawing the value of the setting.
Definition: settings.cpp:460
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:404
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:87
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
GUISettings::missing_strings_threshold
uint8_t missing_strings_threshold
the number of missing strings before showing the warning
Definition: settings_type.h:201
Window::SetWidgetsLoweredState
void SetWidgetsLoweredState(bool lowered_stat, Args... widgets)
Sets the lowered/raised status of a list of widgets.
Definition: window_gui.h:535
WID_GO_BASE_MUSIC_TEXTFILE
@ WID_GO_BASE_MUSIC_TEXTFILE
Open base music readme, changelog (+1) or license (+2).
Definition: settings_widget.h:50
SettingsPage::UnFoldAll
void UnFoldAll() override
Recursively open all (filtered) folds of sub-pages.
Definition: settings_gui.cpp:1827
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:335
CF_NOEURO
static constexpr TimerGameCalendar::Year CF_NOEURO
Currency never switches to the Euro (as far as known).
Definition: currency.h:17
network.h
CurrencySpec::to_euro
TimerGameCalendar::Year to_euro
Year of switching to the Euro. May also be CF_NOEURO or CF_ISEURO.
Definition: currency.h:78
SettingsContainer::FoldAll
void FoldAll()
Recursively close all folds of sub-pages.
Definition: settings_gui.cpp:1661
CONTENT_TYPE_BASE_SOUNDS
@ CONTENT_TYPE_BASE_SOUNDS
The content consists of base sounds.
Definition: tcp_content_type.h:26
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:1955
_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:2248
SA_CENTER
@ SA_CENTER
Center both horizontally and vertically.
Definition: gfx_type.h:355
SettingsPage::Init
void Init(uint8_t level=0) override
Initialization of an entire setting page.
Definition: settings_gui.cpp:1803
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:77
GameSettingsWindow::filter
SettingFilter filter
Filter for the list.
Definition: settings_gui.cpp:2330
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
Window::width
int width
width of the window (number of pixels to the right in x direction)
Definition: window_gui.h:314
CurrencySpec::separator
std::string separator
The thousands separator for this currency.
Definition: currency.h:77
stringfilter_type.h
WID_CC_PREFIX
@ WID_CC_PREFIX
Current prefix.
Definition: settings_widget.h:91
SetMinimalSize
constexpr NWidgetPart SetMinimalSize(int16_t x, int16_t y)
Widget part function for setting the minimal size.
Definition: widget_type.h:1139
MarkWholeScreenDirty
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition: gfx.cpp:1529
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:1274
ClientSettings::network
NetworkSettings network
settings related to the network
Definition: settings_type.h:612
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:606
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:251
LocaleSettings::currency
uint8_t currency
currency we currently use
Definition: settings_type.h:268
DrawSliderWidget
void DrawSliderWidget(Rect r, int min_value, int max_value, int nmarks, int value, SliderMarkFunc *mark_func)
Draw a slider widget with knob at given value.
Definition: slider.cpp:31
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:1372
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:657
WID_GO_BASE_MUSIC_CONTENT_DOWNLOAD
@ WID_GO_BASE_MUSIC_CONTENT_DOWNLOAD
'Get Content' button for base music.
Definition: settings_widget.h:45
SettingEntry::SettingEntry
SettingEntry(const char *name)
Constructor for a single setting in the 'advanced settings' window.
Definition: settings_gui.cpp:1461
SettingFilter
Filter for settings list.
Definition: settings_gui.cpp:1232
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:1226
Scrollbar::GetPosition
size_type GetPosition() const
Gets the position of the first visible element in the list.
Definition: widget_type.h:742
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:1963
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:635
WID_GS_HELP_TEXT
@ WID_GS_HELP_TEXT
Information area to display help text of the selected option.
Definition: settings_widget.h:71
ClientSettings::company
CompanySettings company
default values for per-company settings
Definition: settings_type.h:613
WidgetDimensions::frametext
RectPadding frametext
Padding inside frame with text.
Definition: window_gui.h:43
SettingsContainer
Containers for BaseSettingEntry.
Definition: settings_gui.cpp:1302
BaseSettingEntry::flags
uint8_t flags
Flags of the setting entry.
Definition: settings_gui.cpp:1242
GameSettingsWindow::closing_dropdown
bool closing_dropdown
True, if the dropdown list is currently closing.
Definition: settings_gui.cpp:2328
Window
Data structure for an opened window.
Definition: window_gui.h:276
TextfileType
TextfileType
Additional text files accompanying Tar archives.
Definition: textfile_type.h:14
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:603
SettingEntry
Standard setting.
Definition: settings_gui.cpp:1280
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:2910
GetDropDownListDimension
Dimension GetDropDownListDimension(const DropDownList &list)
Determine width and height required to fully display a DropDownList.
Definition: dropdown.cpp:363
WID_CC_PREFIX_EDIT
@ WID_CC_PREFIX_EDIT
Prefix edit button.
Definition: settings_widget.h:90
DrawBoolButton
void DrawBoolButton(int x, int y, bool state, bool clickable)
Draw a toggle button.
Definition: settings_gui.cpp:2978
SetDataTip
constexpr NWidgetPart SetDataTip(uint32_t data, StringID tip)
Widget part function for setting the data and tooltip.
Definition: widget_type.h:1204
settings_gui.h
_network_available
bool _network_available
is network mode available?
Definition: network.cpp:67
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:1151
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:231
MusicDriver::SetVolume
virtual void SetVolume(uint8_t vol)=0
Set the volume, if possible.
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:392
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:2332
FontCacheSettings::global_aa
bool global_aa
Whether to anti alias all font sizes.
Definition: fontcache.h:206
WID_CC_YEAR_UP
@ WID_CC_YEAR_UP
Up button.
Definition: settings_widget.h:95
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:1421
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:2528
SetAspect
constexpr NWidgetPart SetAspect(float ratio, AspectFlags flags=AspectFlags::ResizeX)
Widget part function for setting the aspect ratio.
Definition: widget_type.h:1297
CurrencySpec::prefix
std::string prefix
Prefix to apply when formatting money in this currency.
Definition: currency.h:79
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:1495
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:3116
Window::SetWidgetsDisabledState
void SetWidgetsDisabledState(bool disab_stat, Args... widgets)
Sets the enabled/disabled status of a list of widgets.
Definition: window_gui.h:524
WID_GO_BASE_SFX_TEXTFILE
@ WID_GO_BASE_SFX_TEXTFILE
Open base SFX readme, changelog (+1) or license (+2).
Definition: settings_widget.h:42
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:615
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:245
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:2300
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:1681
WDP_CENTER
@ WDP_CENTER
Center the window.
Definition: window_gui.h:151
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:2325
ReadLanguagePack
bool ReadLanguagePack(const LanguageMetadata *lang)
Read a particular language.
Definition: strings.cpp:1895
_left_button_clicked
bool _left_button_clicked
Is left mouse button clicked?
Definition: gfx.cpp:42
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:79
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
WID_GO_BASE_MUSIC_OPEN_URL
@ WID_GO_BASE_MUSIC_OPEN_URL
Open base music URL.
Definition: settings_widget.h:49
GetStringBoundingBox
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition: gfx.cpp:851
StringFilter
String filter and state.
Definition: stringfilter_type.h:30
WID_CC_SEPARATOR
@ WID_CC_SEPARATOR
Current separator.
Definition: settings_widget.h:89
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:58
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:611
mixer.h
WID_GO_BASE_GRF_CONTENT_DOWNLOAD
@ WID_GO_BASE_GRF_CONTENT_DOWNLOAD
'Get Content' button for base GRF.
Definition: settings_widget.h:33
AWV_DECREASE
@ AWV_DECREASE
Arrow to the left or in case of RTL to the right.
Definition: widget_type.h:33
BaseSetTextfileWindow::content_type
const StringID content_type
STR_CONTENT_TYPE_xxx for title.
Definition: settings_gui.cpp:98
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:910
CONTENT_TYPE_BASE_MUSIC
@ CONTENT_TYPE_BASE_MUSIC
The content consists of base music.
Definition: tcp_content_type.h:27
dropdown_common_type.h
WID_GO_SURVEY_LINK_BUTTON
@ WID_GO_SURVEY_LINK_BUTTON
Button to open browser to go to the survey website.
Definition: settings_widget.h:58
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:1505
BaseSettingEntry::IsFiltered
bool IsFiltered() const
Check whether an entry is hidden due to filters.
Definition: settings_gui.cpp:1269
MusicSettings::music_vol
uint8_t music_vol
The requested music volume.
Definition: settings_type.h:258
NetworkSettings::participate_survey
ParticipateSurvey participate_survey
Participate in the automated survey.
Definition: settings_type.h:345
RM_ADVANCED
@ RM_ADVANCED
Display settings associated to the "advanced" list.
Definition: settings_gui.cpp:1223
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:1199
SettingEntryFlags
SettingEntryFlags
Flags for SettingEntry.
Definition: settings_gui.cpp:1211
WID_GO_REFRESH_RATE_DROPDOWN
@ WID_GO_REFRESH_RATE_DROPDOWN
Dropdown for all available refresh rates.
Definition: settings_widget.h:54
GUISettings::settings_restriction_mode
uint8_t settings_restriction_mode
selected restriction mode in adv. settings GUI.
Definition: settings_type.h:227
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