OpenTTD Source: src/newgrf_gui.cpp Source File

OpenTTD Source 15.0-RC2

newgrf_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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
10#include "stdafx.h"
11#include "error.h"
12#include "settings_gui.h"
13#include "newgrf.h"
14#include "strings_func.h"
15#include "window_func.h"
16#include "gamelog.h"
17#include "settings_type.h"
18#include "settings_func.h"
19#include "dropdown_type.h"
20#include "dropdown_func.h"
21#include "network/network.h"
22#include "network/network_content.h"
23#include "sortlist_type.h"
24#include "stringfilter_type.h"
25#include "querystring_gui.h"
26#include "core/geometry_func.hpp"
27#include "newgrf_text.h"
28#include "textfile_gui.h"
29#include "tilehighlight_func.h"
30#include "fios.h"
31#include "timer/timer.h"
32#include "timer/timer_window.h"
33#include "zoom_func.h"
34#include "core/string_consumer.hpp"
35
36#include "widgets/newgrf_widget.h"
37#include "widgets/misc_widget.h"
38
39#include "table/sprites.h"
40#include "table/strings.h"
41
42#include "safeguards.h"
43
47 void ShowNewGRFError()
48{
49 /* Do not show errors when entering the main screen */
50 if (_game_mode == GM_MENU) return;
51
52 for (const auto &c : _grfconfig) {
53 /* Only show Fatal and Error level messages */
54 if (c->errors.empty()) continue;
55
56 const GRFError &error = c->errors.back();
57 if (error.severity != STR_NEWGRF_ERROR_MSG_FATAL && error.severity != STR_NEWGRF_ERROR_MSG_ERROR) continue;
58
59 std::vector<StringParameter> params;
60 params.emplace_back(c->GetName());
61 params.emplace_back(error.message != STR_NULL ? error.message : STR_JUST_RAW_STRING);
62 params.emplace_back(error.custom_message);
63 params.emplace_back(c->filename);
64 params.emplace_back(error.data);
65 for (const uint32_t &value : error.param_value) params.emplace_back(value);
66
67 if (error.severity == STR_NEWGRF_ERROR_MSG_FATAL) {
68 ShowErrorMessage(GetEncodedStringWithArgs(STR_NEWGRF_ERROR_FATAL_POPUP, params), {}, WL_CRITICAL);
69 } else {
70 ShowErrorMessage(GetEncodedStringWithArgs(STR_NEWGRF_ERROR_POPUP, params), {}, WL_ERROR);
71 }
72 break;
73 }
74}
75
76static StringID GetGRFPaletteString(uint8_t palette)
77{
78 if (palette & GRFP_BLT_32BPP) {
79 return (palette & GRFP_USE_WINDOWS) ? STR_NEWGRF_SETTINGS_PALETTE_LEGACY_32BPP : STR_NEWGRF_SETTINGS_PALETTE_DEFAULT_32BPP;
80 }
81 return (palette & GRFP_USE_WINDOWS) ? STR_NEWGRF_SETTINGS_PALETTE_LEGACY : STR_NEWGRF_SETTINGS_PALETTE_DEFAULT;
82}
83
84static void ShowNewGRFInfo(const GRFConfig &c, const Rect &r, bool show_params)
85{
86 Rect tr = r.Shrink(WidgetDimensions::scaled.frametext);
87 for (const GRFError &error : c.errors) {
88 std::array<StringParameter, 3 + std::tuple_size_v<decltype(error.param_value)>> params{};
89 auto it = params.begin();
90 *it++ = error.custom_message; // is skipped by built-in messages
91 *it++ = c.filename;
92 *it++ = error.data;
93 for (const uint32_t &value : error.param_value) *it++ = value;
94
95 tr.top = DrawStringMultiLine(tr, GetString(error.severity, GetStringWithArgs(error.message != STR_NULL ? error.message : STR_JUST_RAW_STRING, {params.begin(), it})));
96 }
97
98 /* Draw filename or not if it is not known (GRF sent over internet) */
99 if (!c.filename.empty()) {
100 tr.top = DrawStringMultiLine(tr, GetString(STR_NEWGRF_SETTINGS_FILENAME, c.filename));
101 }
102
103 /* Prepare and draw GRF ID */
104 tr.top = DrawStringMultiLine(tr, GetString(STR_NEWGRF_SETTINGS_GRF_ID, fmt::format("{:08X}", std::byteswap(c.ident.grfid))));
105
106 if ((_settings_client.gui.newgrf_developer_tools || _settings_client.gui.newgrf_show_old_versions) && c.version != 0) {
107 tr.top = DrawStringMultiLine(tr, GetString(STR_NEWGRF_SETTINGS_VERSION, c.version));
108 }
109 if ((_settings_client.gui.newgrf_developer_tools || _settings_client.gui.newgrf_show_old_versions) && c.min_loadable_version != 0) {
110 tr.top = DrawStringMultiLine(tr, GetString(STR_NEWGRF_SETTINGS_MIN_VERSION, c.min_loadable_version));
111 }
112
113 /* Prepare and draw MD5 sum */
114 tr.top = DrawStringMultiLine(tr, GetString(STR_NEWGRF_SETTINGS_MD5SUM, FormatArrayAsHex(c.ident.md5sum)));
115
116 /* Show GRF parameter list */
117 if (show_params) {
118 if (!c.param.empty()) {
119 tr.top = DrawStringMultiLine(tr, GetString(STR_NEWGRF_SETTINGS_PARAMETER, STR_JUST_RAW_STRING, GRFBuildParamList(c)));
120 } else {
121 tr.top = DrawStringMultiLine(tr, GetString(STR_NEWGRF_SETTINGS_PARAMETER, STR_NEWGRF_SETTINGS_PARAMETER_NONE, std::monostate{}));
122 }
123
124 /* Draw the palette of the NewGRF */
125 tr.top = DrawStringMultiLine(tr, GetString(STR_NEWGRF_SETTINGS_PALETTE, GetGRFPaletteString(c.palette)));
126 }
127
128 /* Show flags */
129 if (c.status == GCS_NOT_FOUND) tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_NOT_FOUND);
130 if (c.status == GCS_DISABLED) tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_DISABLED);
131 if (c.flags.Test(GRFConfigFlag::Invalid)) tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_INCOMPATIBLE);
132 if (c.flags.Test(GRFConfigFlag::Compatible)) tr.top = DrawStringMultiLine(tr, STR_NEWGRF_COMPATIBLE_LOADED);
133
134 /* Draw GRF info if it exists */
135 if (auto desc = c.GetDescription(); desc.has_value() && !desc->empty()) {
136 tr.top = DrawStringMultiLine(tr, GetString(STR_JUST_RAW_STRING, std::move(*desc)), TC_BLACK);
137 } else {
138 tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_NO_INFO);
139 }
140}
141
145 struct NewGRFParametersWindow : public Window {
146 static GRFParameterInfo dummy_parameter_info;
147 GRFConfig &grf_config;
148 int32_t clicked_button = INT32_MAX;
149 bool clicked_increase = false;
150 bool clicked_dropdown = false;
151 bool closing_dropdown = false;
152 int32_t clicked_row = INT32_MAX;
153 int line_height = 0;
154 Scrollbar *vscroll = nullptr;
155 bool action14present = false;
156 bool editable = false;
157
158 NewGRFParametersWindow(WindowDesc &desc, bool is_baseset, GRFConfig &c, bool editable) : Window(desc),
159 grf_config(c),
160 editable(editable)
161 {
162 this->action14present = (this->grf_config.num_valid_params != GRFConfig::MAX_NUM_PARAMS || !this->grf_config.param_info.empty());
163
164 this->CreateNestedTree();
165 this->GetWidget<NWidgetCore>(WID_NP_CAPTION)->SetStringTip(is_baseset ? STR_BASEGRF_PARAMETERS_CAPTION : STR_NEWGRF_PARAMETERS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS);
166 this->vscroll = this->GetScrollbar(WID_NP_SCROLLBAR);
167 this->GetWidget<NWidgetStacked>(WID_NP_SHOW_NUMPAR)->SetDisplayedPlane(this->action14present ? SZSP_HORIZONTAL : 0);
168 this->GetWidget<NWidgetStacked>(WID_NP_SHOW_DESCRIPTION)->SetDisplayedPlane(this->action14present ? 0 : SZSP_HORIZONTAL);
169 this->FinishInitNested(); // Initializes 'this->line_height' as side effect.
170
171 this->SetWidgetDisabledState(WID_NP_RESET, !this->editable);
172
173 this->InvalidateData();
174 }
175
181 static GRFParameterInfo &GetDummyParameterInfo(uint nr)
182 {
183 dummy_parameter_info.param_nr = nr;
184 return dummy_parameter_info;
185 }
186
192 bool HasParameterInfo(uint nr) const
193 {
194 return nr < this->grf_config.param_info.size() && this->grf_config.param_info[nr].has_value();
195 }
196
203 GRFParameterInfo &GetParameterInfo(uint nr) const
204 {
205 return this->HasParameterInfo(nr) ? this->grf_config.param_info[nr].value() : GetDummyParameterInfo(nr);
206 }
207
208 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
209 {
210 switch (widget) {
211 case WID_NP_NUMPAR_DEC:
212 case WID_NP_NUMPAR_INC: {
213 size.width = std::max(SETTING_BUTTON_WIDTH / 2, GetCharacterHeight(FS_NORMAL));
214 size.height = std::max(SETTING_BUTTON_HEIGHT, GetCharacterHeight(FS_NORMAL));
215 break;
216 }
217
218 case WID_NP_NUMPAR: {
219 Dimension d = GetStringBoundingBox(GetString(this->GetWidget<NWidgetCore>(widget)->GetString(), GetParamMaxValue(GRFConfig::MAX_NUM_PARAMS)));
220 d.width += padding.width;
221 d.height += padding.height;
222 size = maxdim(size, d);
223 break;
224 }
225
226 case WID_NP_BACKGROUND:
227 this->line_height = std::max(SETTING_BUTTON_HEIGHT, GetCharacterHeight(FS_NORMAL)) + padding.height;
228
229 resize.width = 1;
230 fill.height = resize.height = this->line_height;
231 size.height = 5 * this->line_height;
232 break;
233
234 case WID_NP_DESCRIPTION:
235 /* Minimum size of 4 lines. The 500 is the default size of the window. */
236 Dimension suggestion = {500U - WidgetDimensions::scaled.frametext.Horizontal(), (uint)GetCharacterHeight(FS_NORMAL) * 4 + WidgetDimensions::scaled.frametext.Vertical()};
237 for (const auto &par_info : this->grf_config.param_info) {
238 if (!par_info.has_value()) continue;
239 auto desc = GetGRFStringFromGRFText(par_info->desc);
240 if (!desc.has_value()) continue;
241 Dimension d = GetStringMultiLineBoundingBox(*desc, suggestion);
242 d.height += WidgetDimensions::scaled.frametext.Vertical();
243 suggestion = maxdim(d, suggestion);
244 }
245 size.height = suggestion.height;
246 break;
247 }
248 }
249
250 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
251 {
252 switch (widget) {
253 case WID_NP_NUMPAR:
254 return GetString(STR_NEWGRF_PARAMETERS_NUM_PARAM, this->vscroll->GetCount());
255
256 default:
257 return this->Window::GetWidgetString(widget, stringid);
258 }
259 }
260
261 std::pair<StringParameter, StringParameter> GetValueParams(const GRFParameterInfo &par_info, uint32_t value) const
262 {
263 if (par_info.type == PTYPE_BOOL) return {value != 0 ? STR_CONFIG_SETTING_ON : STR_CONFIG_SETTING_OFF, {}};
264
265 auto it = std::ranges::lower_bound(par_info.value_names, value, std::less{}, &GRFParameterInfo::ValueName::first);
266 if (it != std::end(par_info.value_names) && it->first == value) {
267 if (auto label = GetGRFStringFromGRFText(it->second); label.has_value()) return {STR_JUST_RAW_STRING, *label};
268 }
269
270 return {STR_JUST_INT, value};
271 }
272
273 std::string GetSettingString(const GRFParameterInfo &par_info, int i, uint32_t value) const
274 {
275 auto [param1, param2] = this->GetValueParams(par_info, value);
276 auto name = GetGRFStringFromGRFText(par_info.name);
277 return name.has_value()
278 ? GetString(STR_NEWGRF_PARAMETERS_SETTING, STR_JUST_RAW_STRING, std::string(*name), param1, param2)
279 : GetString(STR_NEWGRF_PARAMETERS_SETTING, STR_NEWGRF_PARAMETERS_DEFAULT_NAME, i + 1, param1, param2);
280 }
281
282 void DrawWidget(const Rect &r, WidgetID widget) const override
283 {
284 if (widget == WID_NP_DESCRIPTION) {
285 if (!this->HasParameterInfo(this->clicked_row)) return;
286 const GRFParameterInfo &par_info = this->GetParameterInfo(this->clicked_row);
287 auto desc = GetGRFStringFromGRFText(par_info.desc);
288 if (!desc.has_value()) return;
289 DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.framerect), *desc, TC_BLACK);
290 return;
291 } else if (widget != WID_NP_BACKGROUND) {
292 return;
293 }
294
295 Rect ir = r.Shrink(WidgetDimensions::scaled.frametext, RectPadding::zero);
296 bool rtl = _current_text_dir == TD_RTL;
297 uint buttons_left = rtl ? ir.right - SETTING_BUTTON_WIDTH : ir.left;
298 Rect tr = ir.Indent(SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_wide, rtl);
299
300 int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2;
301 int text_y_offset = (this->line_height - GetCharacterHeight(FS_NORMAL)) / 2;
302 for (int32_t i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < this->vscroll->GetCount(); i++) {
303 GRFParameterInfo &par_info = this->GetParameterInfo(i);
304 uint32_t current_value = this->grf_config.GetValue(par_info);
305 bool selected = (i == this->clicked_row);
306
307 if (par_info.type == PTYPE_BOOL) {
308 DrawBoolButton(buttons_left, ir.top + button_y_offset, COLOUR_YELLOW, COLOUR_MAUVE, current_value != 0, this->editable);
309 } else if (par_info.type == PTYPE_UINT_ENUM) {
310 if (par_info.complete_labels) {
311 DrawDropDownButton(buttons_left, ir.top + button_y_offset, COLOUR_YELLOW, this->clicked_row == i && this->clicked_dropdown, this->editable);
312 } else {
313 DrawArrowButtons(buttons_left, ir.top + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, this->editable && current_value > par_info.min_value, this->editable && current_value < par_info.max_value);
314 }
315 }
316
317 DrawString(tr.left, tr.right, ir.top + text_y_offset, this->GetSettingString(par_info, i, current_value), selected ? TC_WHITE : TC_LIGHT_BLUE);
318 ir.top += this->line_height;
319 }
320 }
321
322 void OnPaint() override
323 {
324 if (this->closing_dropdown) {
325 this->closing_dropdown = false;
326 this->clicked_dropdown = false;
327 }
328 this->DrawWidgets();
329 }
330
331 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
332 {
333 switch (widget) {
334 case WID_NP_NUMPAR_DEC:
335 if (this->editable && !this->action14present && !this->grf_config.param.empty()) {
336 this->grf_config.param.pop_back();
337 this->InvalidateData();
338 SetWindowDirty(WC_GAME_OPTIONS, WN_GAME_OPTIONS_NEWGRF_STATE);
339 }
340 break;
341
342 case WID_NP_NUMPAR_INC:
343 if (this->editable && !this->action14present && this->grf_config.param.size() < this->grf_config.num_valid_params) {
344 this->grf_config.param.emplace_back(0);
345 this->InvalidateData();
346 SetWindowDirty(WC_GAME_OPTIONS, WN_GAME_OPTIONS_NEWGRF_STATE);
347 }
348 break;
349
350 case WID_NP_BACKGROUND: {
351 if (!this->editable) break;
352 int32_t num = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_NP_BACKGROUND);
353 if (num >= this->vscroll->GetCount()) break;
354
355 if (this->clicked_row != num) {
356 this->CloseChildWindows(WC_QUERY_STRING);
357 this->CloseChildWindows(WC_DROPDOWN_MENU);
358 this->clicked_row = num;
359 this->clicked_dropdown = false;
360 }
361
362 Rect r = this->GetWidget<NWidgetBase>(widget)->GetCurrentRect().Shrink(WidgetDimensions::scaled.frametext, RectPadding::zero);
363 int x = pt.x - r.left;
364 if (_current_text_dir == TD_RTL) x = r.Width() - 1 - x;
365
366 GRFParameterInfo &par_info = this->GetParameterInfo(num);
367
368 /* One of the arrows is clicked */
369 uint32_t old_val = this->grf_config.GetValue(par_info);
370 if (par_info.type != PTYPE_BOOL && IsInsideMM(x, 0, SETTING_BUTTON_WIDTH) && par_info.complete_labels) {
371 if (this->clicked_dropdown) {
372 /* unclick the dropdown */
373 this->CloseChildWindows(WC_DROPDOWN_MENU);
374 this->clicked_dropdown = false;
375 this->closing_dropdown = false;
376 } else {
377 int rel_y = (pt.y - r.top) % this->line_height;
378
379 Rect wi_rect;
380 wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x);;
381 wi_rect.right = wi_rect.left + SETTING_BUTTON_WIDTH - 1;
382 wi_rect.top = pt.y - rel_y + (this->line_height - SETTING_BUTTON_HEIGHT) / 2;
383 wi_rect.bottom = wi_rect.top + SETTING_BUTTON_HEIGHT - 1;
384
385 /* For dropdowns we also have to check the y position thoroughly, the mouse may not above the just opening dropdown */
386 if (pt.y >= wi_rect.top && pt.y <= wi_rect.bottom) {
387 this->clicked_dropdown = true;
388 this->closing_dropdown = false;
389
390 DropDownList list;
391 for (const auto &[value, name] : par_info.value_names) {
392 auto text = GetGRFStringFromGRFText(name);
393 assert(text.has_value()); // ensured by "complete_labels"
394 list.push_back(MakeDropDownListStringItem(GetString(STR_JUST_RAW_STRING, std::string(*text)), value));
395 }
396
397 ShowDropDownListAt(this, std::move(list), old_val, WID_NP_SETTING_DROPDOWN, wi_rect, COLOUR_ORANGE);
398 }
399 }
400 } else if (IsInsideMM(x, 0, SETTING_BUTTON_WIDTH)) {
401 uint32_t val = old_val;
402 if (par_info.type == PTYPE_BOOL) {
403 val = !val;
404 } else {
405 if (x >= SETTING_BUTTON_WIDTH / 2) {
406 /* Increase button clicked */
407 if (val < par_info.max_value) val++;
408 this->clicked_increase = true;
409 } else {
410 /* Decrease button clicked */
411 if (val > par_info.min_value) val--;
412 this->clicked_increase = false;
413 }
414 }
415 if (val != old_val) {
416 this->grf_config.SetValue(par_info, val);
417
418 this->clicked_button = num;
419 this->unclick_timeout.Reset();
420 }
421 } else if (par_info.type == PTYPE_UINT_ENUM && !par_info.complete_labels && click_count >= 2) {
422 /* Display a query box so users can enter a custom value. */
423 ShowQueryString(GetString(STR_JUST_INT, old_val), STR_CONFIG_SETTING_QUERY_CAPTION, 10, this, CS_NUMERAL, {});
424 }
425 this->SetDirty();
426 break;
427 }
428
429 case WID_NP_RESET:
430 if (!this->editable) break;
431 this->grf_config.SetParameterDefaults();
432 this->InvalidateData();
433 SetWindowDirty(WC_GAME_OPTIONS, WN_GAME_OPTIONS_NEWGRF_STATE);
434 break;
435 }
436 }
437
438 void OnQueryTextFinished(std::optional<std::string> str) override
439 {
440 if (!str.has_value() || str->empty()) return;
441 auto value = ParseInteger<int32_t>(*str, 10, true);
442 if (!value.has_value()) return;
443 GRFParameterInfo &par_info = this->GetParameterInfo(this->clicked_row);
444 this->grf_config.SetValue(par_info, *value);
445 this->SetDirty();
446 }
447
448 void OnDropdownSelect(WidgetID widget, int index, int) override
449 {
450 if (widget != WID_NP_SETTING_DROPDOWN) return;
451 assert(this->clicked_dropdown);
452 GRFParameterInfo &par_info = this->GetParameterInfo(this->clicked_row);
453 this->grf_config.SetValue(par_info, index);
454 this->SetDirty();
455 }
456
457 void OnDropdownClose(Point, WidgetID widget, int, int, bool) override
458 {
459 if (widget != WID_NP_SETTING_DROPDOWN) return;
460 /* We cannot raise the dropdown button just yet. OnClick needs some hint, whether
461 * the same dropdown button was clicked again, and then not open the dropdown again.
462 * So, we only remember that it was closed, and process it on the next OnPaint, which is
463 * after OnClick. */
464 assert(this->clicked_dropdown);
465 this->closing_dropdown = true;
466 this->SetDirty();
467 }
468
469 void OnResize() override
470 {
471 this->vscroll->SetCapacityFromWidget(this, WID_NP_BACKGROUND);
472 }
473
479 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
480 {
481 if (!gui_scope) return;
482 if (!this->action14present) {
483 this->SetWidgetDisabledState(WID_NP_NUMPAR_DEC, !this->editable || this->grf_config.param.empty());
484 this->SetWidgetDisabledState(WID_NP_NUMPAR_INC, !this->editable || std::size(this->grf_config.param) >= this->grf_config.num_valid_params);
485 }
486
487 this->vscroll->SetCount(this->action14present ? this->grf_config.num_valid_params : this->grf_config.param.size());
488 if (this->clicked_row != INT32_MAX && this->clicked_row >= this->vscroll->GetCount()) {
489 this->clicked_row = INT32_MAX;
490 this->CloseChildWindows(WC_QUERY_STRING);
491 }
492 }
493
495 TimeoutTimer<TimerWindow> unclick_timeout = {std::chrono::milliseconds(150), [this]() {
496 this->clicked_button = INT32_MAX;
497 this->SetDirty();
498 }};
499};
500 GRFParameterInfo NewGRFParametersWindow::dummy_parameter_info(0);
501
502
503static constexpr std::initializer_list<NWidgetPart> _nested_newgrf_parameter_widgets = {
504 NWidget(NWID_HORIZONTAL),
505 NWidget(WWT_CLOSEBOX, COLOUR_MAUVE),
506 NWidget(WWT_CAPTION, COLOUR_MAUVE, WID_NP_CAPTION),
507 NWidget(WWT_DEFSIZEBOX, COLOUR_MAUVE),
508 EndContainer(),
509 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NP_SHOW_NUMPAR),
510 NWidget(WWT_PANEL, COLOUR_MAUVE), SetResize(1, 0), SetFill(1, 0), SetPIP(4, 0, 4),
511 NWidget(NWID_HORIZONTAL), SetPIP(4, 0, 4),
512 NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_NP_NUMPAR_DEC), SetMinimalSize(12, 12), SetArrowWidgetTypeTip(AWV_DECREASE),
513 NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_NP_NUMPAR_INC), SetMinimalSize(12, 12), SetArrowWidgetTypeTip(AWV_INCREASE),
514 NWidget(WWT_TEXT, INVALID_COLOUR, WID_NP_NUMPAR), SetResize(1, 0), SetFill(1, 0), SetPadding(0, 0, 0, 4),
515 EndContainer(),
516 EndContainer(),
517 EndContainer(),
518 NWidget(NWID_HORIZONTAL),
519 NWidget(WWT_MATRIX, COLOUR_MAUVE, WID_NP_BACKGROUND), SetMinimalSize(188, 182), SetResize(1, 1), SetFill(1, 0), SetMatrixDataTip(1, 0), SetScrollbar(WID_NP_SCROLLBAR),
520 NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, WID_NP_SCROLLBAR),
521 EndContainer(),
522 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NP_SHOW_DESCRIPTION),
523 NWidget(WWT_PANEL, COLOUR_MAUVE, WID_NP_DESCRIPTION), SetResize(1, 0), SetFill(1, 0),
524 EndContainer(),
525 EndContainer(),
526 NWidget(NWID_HORIZONTAL),
527 NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_NP_RESET), SetStringTip(STR_NEWGRF_PARAMETERS_RESET, STR_NEWGRF_PARAMETERS_RESET_TOOLTIP),
528 NWidget(WWT_PANEL, COLOUR_MAUVE), SetResize(1, 0), SetFill(1, 0),
529 EndContainer(),
530 NWidget(WWT_RESIZEBOX, COLOUR_MAUVE),
531 EndContainer(),
532};
533
535 static WindowDesc _newgrf_parameters_desc(
536 WDP_CENTER, "settings_newgrf_config", 500, 208,
537 WC_GRF_PARAMETERS, WC_NONE,
538 {},
539 _nested_newgrf_parameter_widgets
540);
541
542void OpenGRFParameterWindow(bool is_baseset, GRFConfig &c, bool editable)
543{
544 CloseWindowByClass(WC_GRF_PARAMETERS);
545 new NewGRFParametersWindow(_newgrf_parameters_desc, is_baseset, c, editable);
546}
547
549 struct NewGRFTextfileWindow : public TextfileWindow {
550 const GRFConfig *grf_config = nullptr;
551
552 NewGRFTextfileWindow(Window *parent, TextfileType file_type, const GRFConfig *c) : TextfileWindow(parent, file_type), grf_config(c)
553 {
554 this->ConstructWindow();
555
556 auto textfile = this->grf_config->GetTextfile(file_type);
557 this->LoadTextfile(textfile.value(), NEWGRF_DIR);
558 }
559
560 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
561 {
562 if (widget == WID_TF_CAPTION) {
563 return GetString(stringid, STR_CONTENT_TYPE_NEWGRF, this->grf_config->GetName());
564 }
565
566 return this->Window::GetWidgetString(widget, stringid);
567 }
568};
569
570void ShowNewGRFTextfileWindow(Window *parent, TextfileType file_type, const GRFConfig *c)
571{
572 parent->CloseChildWindowById(WC_TEXTFILE, file_type);
573 new NewGRFTextfileWindow(parent, file_type, c);
574}
575
576 typedef std::map<uint32_t, const GRFConfig *> GrfIdMap;
577
583 static void FillGrfidMap(const GRFConfigList &lst, GrfIdMap &grfid_map)
584{
585 for (const auto &c : lst) {
586 grfid_map.emplace(c->ident.grfid, c.get());
587 }
588}
589
590static void NewGRFConfirmationCallback(Window *w, bool confirmed);
591static void ShowSavePresetWindow(std::string_view initial_text);
592
596 struct NewGRFWindow : public Window, NewGRFScanCallback {
597 typedef GUIList<const GRFConfig *, std::nullptr_t, StringFilter &> GUIGRFConfigList;
598
599 static const uint EDITBOX_MAX_SIZE = 50;
600
601 static Listing last_sorting;
602 static Filtering last_filtering;
603 static const std::initializer_list<GUIGRFConfigList::SortFunction * const> sorter_funcs;
604 static const std::initializer_list<GUIGRFConfigList::FilterFunction * const> filter_funcs;
605
606 GUIGRFConfigList avails{};
607 const GRFConfig *avail_sel = nullptr;
608 int avail_pos = -1;
609 StringFilter string_filter{};
610 QueryString filter_editbox;
611
612 StringList grf_presets{};
613
614 GRFConfigList actives{};
615 GRFConfig *active_sel = nullptr;
616
617 GRFConfigList &orig_list;
618 bool editable = false;
619 bool show_params = false;
620 bool execute = false;
621 int preset = -1;
622 int active_over = -1;
623 bool modified = false;
624
625 Scrollbar *vscroll = nullptr;
626 Scrollbar *vscroll2 = nullptr;
627
628 NewGRFWindow(WindowDesc &desc, bool editable, bool show_params, bool execute, GRFConfigList &orig_list) : Window(desc), filter_editbox(EDITBOX_MAX_SIZE), orig_list(orig_list)
629 {
630 this->editable = editable;
631 this->execute = execute;
632 this->show_params = show_params;
633
634 CopyGRFConfigList(this->actives, orig_list, false);
635 this->grf_presets = GetGRFPresetList();
636
637 this->CreateNestedTree();
638 this->vscroll = this->GetScrollbar(WID_NS_SCROLLBAR);
639 this->vscroll2 = this->GetScrollbar(WID_NS_SCROLL2BAR);
640
641 this->GetWidget<NWidgetStacked>(WID_NS_SHOW_REMOVE)->SetDisplayedPlane(this->editable ? 0 : 1);
642 this->GetWidget<NWidgetStacked>(WID_NS_SHOW_EDIT)->SetDisplayedPlane(this->editable ? 0 : (this->show_params ? 1 : SZSP_HORIZONTAL));
643 this->GetWidget<NWidgetStacked>(WID_NS_SHOW_APPLY)->SetDisplayedPlane(this->editable && this->execute ? 0 : SZSP_VERTICAL);
644 this->FinishInitNested(WN_GAME_OPTIONS_NEWGRF_STATE);
645
646 this->querystrings[WID_NS_FILTER] = &this->filter_editbox;
647 this->filter_editbox.cancel_button = QueryString::ACTION_CLEAR;
648 if (editable) {
649 this->SetFocusedWidget(WID_NS_FILTER);
650 } else {
651 this->DisableWidget(WID_NS_FILTER);
652 }
653
654 this->avails.SetListing(this->last_sorting);
655 this->avails.SetFiltering(this->last_filtering);
656 this->avails.SetSortFuncs(this->sorter_funcs);
657 this->avails.SetFilterFuncs(this->filter_funcs);
658 this->avails.ForceRebuild();
659
660 this->OnInvalidateData(GOID_NEWGRF_CURRENT_LOADED);
661 }
662
663 void Close([[maybe_unused]] int data = 0) override
664 {
665 CloseWindowByClass(WC_GRF_PARAMETERS);
666 CloseWindowByClass(WC_SAVE_PRESET);
667
668 if (this->editable && this->modified && !this->execute && !_exit_game) {
669 CopyGRFConfigList(this->orig_list, this->actives, true);
670 ResetGRFConfig(false);
671 ReloadNewGRFData();
672 }
673
674 this->Window::Close();
675 }
676
677 int GetCurrentActivePosition() const
678 {
679 if (this->active_sel != nullptr) {
680 auto it = std::ranges::find_if(this->actives, [this](const auto &c) { return c.get() == this->active_sel; });
681 if (it != std::end(this->actives)) return static_cast<int>(std::distance(std::begin(this->actives), it));
682 }
683 return -1;
684 }
685
690 bool CanUpgradeCurrent()
691 {
692 GrfIdMap grfid_map;
693 FillGrfidMap(this->actives, grfid_map);
694
695 for (const auto &a : _all_grfs) {
696 GrfIdMap::const_iterator iter = grfid_map.find(a->ident.grfid);
697 if (iter != grfid_map.end() && a->version > iter->second->version) return true;
698 }
699 return false;
700 }
701
703 void UpgradeCurrent()
704 {
705 GrfIdMap grfid_map;
706 FillGrfidMap(this->actives, grfid_map);
707
708 for (const auto &a : _all_grfs) {
709 GrfIdMap::iterator iter = grfid_map.find(a->ident.grfid);
710 if (iter == grfid_map.end() || iter->second->version >= a->version) continue;
711
712 auto c = std::ranges::find_if(this->actives, [&iter](const auto &grfconfig) { return grfconfig.get() == iter->second; });
713 assert(c != std::end(this->actives));
714 auto d = std::make_unique<GRFConfig>(*a);
715 if (d->IsCompatible((*c)->version)) {
716 d->CopyParams(**c);
717 } else {
718 d->SetParameterDefaults();
719 }
720 if (this->active_sel == c->get()) {
721 CloseWindowByClass(WC_GRF_PARAMETERS);
722 this->CloseChildWindows(WC_TEXTFILE);
723 this->active_sel = nullptr;
724 }
725 *c = std::move(d);
726 iter->second = c->get();
727 }
728 }
729
730 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
731 {
732 switch (widget) {
733 case WID_NS_FILE_LIST:
734 {
735 Dimension d = maxdim(GetScaledSpriteSize(SPR_SQUARE), GetScaledSpriteSize(SPR_WARNING_SIGN));
736 fill.height = resize.height = std::max<uint>(d.height + 2U, GetCharacterHeight(FS_NORMAL));
737 size.height = std::max(size.height, padding.height + 6 * resize.height);
738 break;
739 }
740
741 case WID_NS_AVAIL_LIST:
742 {
743 Dimension d = maxdim(GetScaledSpriteSize(SPR_SQUARE), GetScaledSpriteSize(SPR_WARNING_SIGN));
744 fill.height = resize.height = std::max<uint>(d.height + 2U, GetCharacterHeight(FS_NORMAL));
745 size.height = std::max(size.height, padding.height + 8 * resize.height);
746 break;
747 }
748
749 case WID_NS_NEWGRF_INFO_TITLE: {
750 Dimension dim = GetStringBoundingBox(STR_NEWGRF_SETTINGS_INFO_TITLE);
751 size.height = std::max(size.height, dim.height + WidgetDimensions::scaled.frametext.Vertical());
752 size.width = std::max(size.width, dim.width + WidgetDimensions::scaled.frametext.Horizontal());
753 break;
754 }
755
756 case WID_NS_NEWGRF_INFO:
757 size.height = std::max<uint>(size.height, WidgetDimensions::scaled.framerect.Vertical() + 10 * GetCharacterHeight(FS_NORMAL));
758 break;
759
760 case WID_NS_PRESET_LIST: {
761 Dimension d = GetStringBoundingBox(STR_NUM_CUSTOM);
762 for (const auto &i : this->grf_presets) {
763 d = maxdim(d, GetStringBoundingBox(GetString(STR_JUST_RAW_STRING, i)));
764 }
765 d.width += padding.width;
766 size = maxdim(d, size);
767 break;
768 }
769
770 case WID_NS_CONTENT_DOWNLOAD:
771 case WID_NS_CONTENT_DOWNLOAD2: {
772 Dimension d = GetStringBoundingBox(STR_NEWGRF_SETTINGS_FIND_MISSING_CONTENT_BUTTON);
773 size = maxdim(d, GetStringBoundingBox(STR_INTRO_ONLINE_CONTENT));
774 size.width += padding.width;
775 size.height += padding.height;
776 break;
777 }
778 }
779 }
780
781 void OnResize() override
782 {
783 this->vscroll->SetCapacityFromWidget(this, WID_NS_FILE_LIST, WidgetDimensions::scaled.framerect.Vertical());
784 this->vscroll2->SetCapacityFromWidget(this, WID_NS_AVAIL_LIST, WidgetDimensions::scaled.framerect.Vertical());
785 }
786
787 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
788 {
789 switch (widget) {
790 case WID_NS_PRESET_LIST:
791 if (this->preset == -1) return GetString(STR_NUM_CUSTOM);
792
793 return this->grf_presets[this->preset];
794
795 default:
796 return this->Window::GetWidgetString(widget, stringid);
797 }
798 }
799
805 inline PaletteID GetPalette(const GRFConfig &c) const
806 {
807 PaletteID pal;
808
809 /* Pick a colour */
810 switch (c.status) {
811 case GCS_NOT_FOUND:
812 case GCS_DISABLED:
813 pal = PALETTE_TO_RED;
814 break;
815 case GCS_ACTIVATED:
816 pal = PALETTE_TO_GREEN;
817 break;
818 default:
819 pal = PALETTE_TO_BLUE;
820 break;
821 }
822
823 /* Do not show a "not-failure" colour when it actually failed to load */
824 if (pal != PALETTE_TO_RED) {
825 if (c.flags.Test(GRFConfigFlag::Static)) {
826 pal = PALETTE_TO_GREY;
827 } else if (c.flags.Test(GRFConfigFlag::Compatible)) {
828 pal = PALETTE_TO_ORANGE;
829 }
830 }
831
832 return pal;
833 }
834
835 void DrawWidget(const Rect &r, WidgetID widget) const override
836 {
837 switch (widget) {
838 case WID_NS_FILE_LIST: {
839 const Rect br = r.Shrink(WidgetDimensions::scaled.bevel);
840 GfxFillRect(br, PC_BLACK);
841
842 Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
843 uint step_height = this->GetWidget<NWidgetBase>(WID_NS_FILE_LIST)->resize_y;
844 Dimension square = GetSpriteSize(SPR_SQUARE);
845 Dimension warning = GetSpriteSize(SPR_WARNING_SIGN);
846 int square_offset_y = (step_height - square.height) / 2;
847 int warning_offset_y = (step_height - warning.height) / 2;
848 int offset_y = (step_height - GetCharacterHeight(FS_NORMAL)) / 2;
849
850 bool rtl = _current_text_dir == TD_RTL;
851 uint text_left = rtl ? tr.left : tr.left + square.width + 13;
852 uint text_right = rtl ? tr.right - square.width - 13 : tr.right;
853 uint square_left = rtl ? tr.right - square.width - 3 : tr.left + 3;
854 uint warning_left = rtl ? tr.right - square.width - warning.width - 8 : tr.left + square.width + 8;
855
856 int i = 0;
857 for (const auto &c : this->actives) {
858 if (this->vscroll->IsVisible(i)) {
859 std::string text = c->GetName();
860 bool h = (this->active_sel == c.get());
861 PaletteID pal = this->GetPalette(*c);
862
863 if (h) {
864 GfxFillRect(br.left, tr.top, br.right, tr.top + step_height - 1, PC_DARK_BLUE);
865 } else if (i == this->active_over) {
866 /* Get index of current selection. */
867 int active_sel_pos = this->GetCurrentActivePosition();
868 if (active_sel_pos != this->active_over) {
869 uint top = (active_sel_pos < 0 || this->active_over < active_sel_pos) ? tr.top + 1 : tr.top + step_height - 2;
870 GfxFillRect(tr.left, top - 1, tr.right, top + 1, PC_GREY);
871 }
872 }
873 DrawSprite(SPR_SQUARE, pal, square_left, tr.top + square_offset_y);
874 if (!c->errors.empty()) DrawSprite(SPR_WARNING_SIGN, 0, warning_left, tr.top + warning_offset_y);
875 uint txtoffset = c->errors.empty() ? 0 : warning.width;
876 DrawString(text_left + (rtl ? 0 : txtoffset), text_right - (rtl ? txtoffset : 0), tr.top + offset_y, std::move(text), h ? TC_WHITE : TC_ORANGE);
877 tr.top += step_height;
878 }
879 i++;
880 }
881 if (i == this->active_over && this->vscroll->IsVisible(i)) { // Highlight is after the last GRF entry.
882 GfxFillRect(tr.left, tr.top, tr.right, tr.top + 2, PC_GREY);
883 }
884 break;
885 }
886
887 case WID_NS_AVAIL_LIST: {
888 const Rect br = r.Shrink(WidgetDimensions::scaled.bevel);
889 GfxFillRect(br, this->active_over == -2 ? PC_DARK_GREY : PC_BLACK);
890
891 Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
892 uint step_height = this->GetWidget<NWidgetBase>(WID_NS_AVAIL_LIST)->resize_y;
893 int offset_y = (step_height - GetCharacterHeight(FS_NORMAL)) / 2;
894
895 auto [first, last] = this->vscroll2->GetVisibleRangeIterators(this->avails);
896 for (auto it = first; it != last; ++it) {
897 const GRFConfig *c = *it;
898 bool h = (c == this->avail_sel);
899 std::string text = c->GetName();
900
901 if (h) GfxFillRect(br.left, tr.top, br.right, tr.top + step_height - 1, PC_DARK_BLUE);
902 DrawString(tr.left, tr.right, tr.top + offset_y, std::move(text), h ? TC_WHITE : TC_SILVER);
903 tr.top += step_height;
904 }
905 break;
906 }
907
908 case WID_NS_NEWGRF_INFO_TITLE: {
909 /* Create the nice darker rectangle at the details top. */
910 GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), GetColourGradient(COLOUR_MAUVE, SHADE_NORMAL));
911 DrawString(r.left, r.right, CentreBounds(r.top, r.bottom, GetCharacterHeight(FS_NORMAL)), STR_NEWGRF_SETTINGS_INFO_TITLE, TC_FROMSTRING, SA_HOR_CENTER);
912 break;
913 }
914
915 case WID_NS_NEWGRF_INFO: {
916 const GRFConfig *selected = this->active_sel;
917 if (selected == nullptr) selected = this->avail_sel;
918 if (selected != nullptr) {
919 ShowNewGRFInfo(*selected, r, this->show_params);
920 }
921 break;
922 }
923 }
924 }
925
926 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
927 {
928 if (widget >= WID_NS_NEWGRF_TEXTFILE && widget < WID_NS_NEWGRF_TEXTFILE + TFT_CONTENT_END) {
929 if (this->active_sel == nullptr && this->avail_sel == nullptr) return;
930
931 ShowNewGRFTextfileWindow(this, (TextfileType)(widget - WID_NS_NEWGRF_TEXTFILE), this->active_sel != nullptr ? this->active_sel : this->avail_sel);
932 return;
933 }
934
935 switch (widget) {
936 case WID_NS_PRESET_LIST: {
937 DropDownList list;
938
939 /* Add 'None' option for clearing list */
940 list.push_back(MakeDropDownListStringItem(STR_NONE, -1));
941
942 for (uint i = 0; i < this->grf_presets.size(); i++) {
943 list.push_back(MakeDropDownListStringItem(std::string{this->grf_presets[i]}, i));
944 }
945
946 this->CloseChildWindows(WC_QUERY_STRING); // Remove the parameter query window
947 ShowDropDownList(this, std::move(list), this->preset, WID_NS_PRESET_LIST);
948 break;
949 }
950
951 case WID_NS_OPEN_URL: {
952 const GRFConfig *c = (this->avail_sel == nullptr) ? this->active_sel : this->avail_sel;
953 auto url = c->GetURL();
954 if (url.has_value()) OpenBrowser(std::move(*url));
955 break;
956 }
957
958 case WID_NS_PRESET_SAVE:
959 ShowSavePresetWindow((this->preset == -1) ? std::string_view{} : this->grf_presets[this->preset]);
960 break;
961
962 case WID_NS_PRESET_DELETE:
963 if (this->preset == -1) return;
964
965 DeleteGRFPresetFromConfig(this->grf_presets[this->preset]);
966 this->grf_presets = GetGRFPresetList();
967 this->preset = -1;
968 this->InvalidateData();
969 this->CloseChildWindows(WC_QUERY_STRING); // Remove the parameter query window
970 break;
971
972 case WID_NS_MOVE_UP: { // Move GRF up
973 if (this->active_sel == nullptr || !this->editable) break;
974
975 int pos = this->GetCurrentActivePosition();
976 if (pos <= 0) break;
977
978 std::swap(this->actives[pos - 1], this->actives[pos]);
979
980 this->vscroll->ScrollTowards(pos - 1);
981 this->preset = -1;
982 this->InvalidateData(GOID_NEWGRF_LIST_EDITED);
983 break;
984 }
985
986 case WID_NS_MOVE_DOWN: { // Move GRF down
987 if (this->active_sel == nullptr || !this->editable) break;
988
989 int pos = this->GetCurrentActivePosition();
990 if (pos == -1 || static_cast<size_t>(pos) >= this->actives.size() - 1) break;
991
992 std::swap(this->actives[pos], this->actives[pos + 1]);
993
994 this->vscroll->ScrollTowards(pos + 1);
995 this->preset = -1;
996 this->InvalidateData(GOID_NEWGRF_LIST_EDITED);
997 break;
998 }
999
1000 case WID_NS_FILE_LIST: { // Select an active GRF.
1001 ResetObjectToPlace();
1002
1003 const GRFConfig *old_sel = this->active_sel;
1004 uint i = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_NS_FILE_LIST, WidgetDimensions::scaled.framerect.top);
1005 if (i < this->actives.size()) {
1006 this->active_sel = this->actives[i].get();
1007 } else {
1008 this->active_sel = nullptr;
1009 }
1010 if (this->active_sel != old_sel) {
1011 CloseWindowByClass(WC_GRF_PARAMETERS);
1012 this->CloseChildWindows(WC_TEXTFILE);
1013 }
1014 this->avail_sel = nullptr;
1015 this->avail_pos = -1;
1016
1017 this->InvalidateData();
1018 if (click_count == 1) {
1019 if (this->editable && this->active_sel != nullptr) SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this);
1020 break;
1021 }
1022 /* With double click, continue */
1023 [[fallthrough]];
1024 }
1025
1026 case WID_NS_REMOVE: { // Remove GRF
1027 if (this->active_sel == nullptr || !this->editable) break;
1028 CloseWindowByClass(WC_GRF_PARAMETERS);
1029 this->CloseChildWindows(WC_TEXTFILE);
1030
1031 /* Choose the next GRF file to be the selected file. */
1032 int pos = this->GetCurrentActivePosition();
1033 if (pos < 0) break;
1034
1035 auto it = std::next(std::begin(this->actives), pos);
1036 it = this->actives.erase(it);
1037 if (this->actives.empty()) {
1038 this->active_sel = nullptr;
1039 } else if (it == std::end(this->actives)) {
1040 this->active_sel = this->actives.back().get();
1041 } else {
1042 this->active_sel = it->get();
1043 }
1044 this->preset = -1;
1045 this->avail_pos = -1;
1046 this->avail_sel = nullptr;
1047 this->avails.ForceRebuild();
1048 this->InvalidateData(GOID_NEWGRF_LIST_EDITED);
1049 break;
1050 }
1051
1052 case WID_NS_UPGRADE: { // Upgrade GRF.
1053 if (!this->editable || this->actives.empty()) break;
1054 UpgradeCurrent();
1055 this->InvalidateData(GOID_NEWGRF_LIST_EDITED);
1056 break;
1057 }
1058
1059 case WID_NS_AVAIL_LIST: { // Select a non-active GRF.
1060 ResetObjectToPlace();
1061
1062 auto it = this->vscroll2->GetScrolledItemFromWidget(this->avails, pt.y, this, WID_NS_AVAIL_LIST, WidgetDimensions::scaled.framerect.top);
1063 this->active_sel = nullptr;
1064 CloseWindowByClass(WC_GRF_PARAMETERS);
1065 if (it != std::end(this->avails)) {
1066 if (this->avail_sel != *it) this->CloseChildWindows(WC_TEXTFILE);
1067 this->avail_sel = *it;
1068 this->avail_pos = static_cast<int>(std::distance(std::begin(this->avails), it));
1069 }
1070 this->InvalidateData();
1071 if (click_count == 1) {
1072 if (this->editable && this->avail_sel != nullptr && !this->avail_sel->flags.Test(GRFConfigFlag::Invalid)) SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this);
1073 break;
1074 }
1075 /* With double click, continue */
1076 [[fallthrough]];
1077 }
1078
1079 case WID_NS_ADD:
1080 if (this->avail_sel == nullptr || !this->editable || this->avail_sel->flags.Test(GRFConfigFlag::Invalid)) break;
1081
1082 this->AddGRFToActive();
1083 break;
1084
1085 case WID_NS_APPLY_CHANGES: // Apply changes made to GRF list
1086 if (!this->editable) break;
1087
1088 ShowQuery(
1089 GetEncodedString(STR_NEWGRF_POPUP_CAUTION_CAPTION),
1090 GetEncodedString(STR_NEWGRF_CONFIRMATION_TEXT),
1091 this,
1092 NewGRFConfirmationCallback
1093 );
1094
1095 this->CloseChildWindows(WC_QUERY_STRING); // Remove the parameter query window
1096 break;
1097
1098 case WID_NS_VIEW_PARAMETERS:
1099 case WID_NS_SET_PARAMETERS: { // Edit parameters
1100 if (this->active_sel == nullptr || !this->show_params || this->active_sel->num_valid_params == 0) break;
1101
1102 OpenGRFParameterWindow(false, *this->active_sel, this->editable);
1103 this->InvalidateData(GOID_NEWGRF_CHANGES_MADE);
1104 break;
1105 }
1106
1107 case WID_NS_TOGGLE_PALETTE:
1108 if (this->active_sel != nullptr && this->editable) {
1109 this->active_sel->palette ^= GRFP_USE_MASK;
1110 this->SetDirty();
1111 this->InvalidateData(GOID_NEWGRF_CHANGES_MADE);
1112 }
1113 break;
1114
1115 case WID_NS_CONTENT_DOWNLOAD:
1116 case WID_NS_CONTENT_DOWNLOAD2:
1117 if (!_network_available) {
1118 ShowErrorMessage(GetEncodedString(STR_NETWORK_ERROR_NOTAVAILABLE), {}, WL_ERROR);
1119 } else {
1120 this->CloseChildWindows(WC_QUERY_STRING); // Remove the parameter query window
1121
1122 ShowMissingContentWindow(this->actives);
1123 }
1124 break;
1125
1126 case WID_NS_RESCAN_FILES:
1127 case WID_NS_RESCAN_FILES2:
1128 RequestNewGRFScan(this);
1129 break;
1130 }
1131 }
1132
1133 void OnNewGRFsScanned() override
1134 {
1135 if (this->active_sel == nullptr) this->CloseChildWindows(WC_TEXTFILE);
1136 this->avail_sel = nullptr;
1137 this->avail_pos = -1;
1138 this->avails.ForceRebuild();
1139 this->CloseChildWindows(WC_QUERY_STRING); // Remove the parameter query window
1140 }
1141
1142 void OnDropdownSelect(WidgetID widget, int index, int) override
1143 {
1144 if (widget != WID_NS_PRESET_LIST) return;
1145 if (!this->editable) return;
1146
1147 ClearGRFConfigList(this->actives);
1148 this->preset = index;
1149
1150 if (index != -1) {
1151 this->actives = LoadGRFPresetFromConfig(this->grf_presets[index]);
1152 }
1153 this->avails.ForceRebuild();
1154
1155 ResetObjectToPlace();
1156 CloseWindowByClass(WC_GRF_PARAMETERS);
1157 this->CloseChildWindows(WC_TEXTFILE);
1158 this->active_sel = nullptr;
1159 this->InvalidateData(GOID_NEWGRF_CHANGES_MADE);
1160 }
1161
1162 void OnQueryTextFinished(std::optional<std::string> str) override
1163 {
1164 if (!str.has_value()) return;
1165
1166 SaveGRFPresetToConfig(*str, this->actives);
1167 this->grf_presets = GetGRFPresetList();
1168
1169 /* Switch to this preset */
1170 for (uint i = 0; i < this->grf_presets.size(); i++) {
1171 if (this->grf_presets[i] == str) {
1172 this->preset = i;
1173 break;
1174 }
1175 }
1176
1177 this->InvalidateData();
1178 }
1179
1183 void UpdateScrollBars()
1184 {
1185 /* Update scrollbars */
1186 this->vscroll->SetCount(this->actives.size() + 1); // Reserve empty space for drag and drop handling.
1187
1188 if (this->avail_pos >= 0) this->vscroll2->ScrollTowards(this->avail_pos);
1189 }
1190
1196 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
1197 {
1198 if (!gui_scope) return;
1199 switch (data) {
1200 default:
1201 /* Nothing important to do */
1202 break;
1203
1204 case GOID_NEWGRF_RESCANNED:
1205 /* Search the list for items that are now found and mark them as such. */
1206 for (auto &c : this->actives) {
1207 bool compatible = c->flags.Test(GRFConfigFlag::Compatible);
1208 if (c->status != GCS_NOT_FOUND && !compatible) continue;
1209
1210 const GRFConfig *f = FindGRFConfig(c->ident.grfid, FGCM_EXACT, compatible ? &c->original_md5sum : &c->ident.md5sum);
1211 if (f == nullptr || f->flags.Test(GRFConfigFlag::Invalid)) continue;
1212
1213 c = std::make_unique<GRFConfig>(*f);
1214 }
1215
1216 this->avails.ForceRebuild();
1217 [[fallthrough]];
1218
1219 case GOID_NEWGRF_CURRENT_LOADED:
1220 this->modified = false;
1221 UpdateScrollBars();
1222 break;
1223
1224 case GOID_NEWGRF_LIST_EDITED:
1225 this->preset = -1;
1226 [[fallthrough]];
1227
1228 case GOID_NEWGRF_CHANGES_MADE:
1229 UpdateScrollBars();
1230
1231 /* Changes have been made to the list of active NewGRFs */
1232 this->modified = true;
1233
1234 break;
1235 }
1236
1237 this->BuildAvailables();
1238
1239 this->SetWidgetDisabledState(WID_NS_APPLY_CHANGES, !((this->editable && this->modified) || _settings_client.gui.newgrf_developer_tools));
1240 this->SetWidgetsDisabledState(!this->editable,
1241 WID_NS_PRESET_LIST,
1242 WID_NS_TOGGLE_PALETTE
1243 );
1244 this->SetWidgetDisabledState(WID_NS_ADD, !this->editable || this->avail_sel == nullptr || this->avail_sel->flags.Test(GRFConfigFlag::Invalid));
1245 this->SetWidgetDisabledState(WID_NS_UPGRADE, !this->editable || this->actives.empty() || !this->CanUpgradeCurrent());
1246
1247 bool disable_all = this->active_sel == nullptr || !this->editable;
1248 this->SetWidgetsDisabledState(disable_all,
1249 WID_NS_REMOVE,
1250 WID_NS_MOVE_UP,
1251 WID_NS_MOVE_DOWN
1252 );
1253
1254 const GRFConfig *selected_config = (this->avail_sel == nullptr) ? this->active_sel : this->avail_sel;
1255 for (TextfileType tft = TFT_CONTENT_BEGIN; tft < TFT_CONTENT_END; tft++) {
1256 this->SetWidgetDisabledState(WID_NS_NEWGRF_TEXTFILE + tft, selected_config == nullptr || !selected_config->GetTextfile(tft).has_value());
1257 }
1258 this->SetWidgetDisabledState(WID_NS_OPEN_URL, selected_config == nullptr || !selected_config->GetURL().has_value());
1259
1260 this->SetWidgetDisabledState(WID_NS_SET_PARAMETERS, !this->show_params || this->active_sel == nullptr || this->active_sel->num_valid_params == 0);
1261 this->SetWidgetDisabledState(WID_NS_VIEW_PARAMETERS, !this->show_params || this->active_sel == nullptr || this->active_sel->num_valid_params == 0);
1262 this->SetWidgetDisabledState(WID_NS_TOGGLE_PALETTE, disable_all ||
1263 (!(_settings_client.gui.newgrf_developer_tools || _settings_client.gui.scenario_developer) && ((selected_config->palette & GRFP_GRF_MASK) != GRFP_GRF_UNSET)));
1264
1265 if (!disable_all) {
1266 /* All widgets are now enabled, so disable widgets we can't use */
1267 if (this->active_sel == this->actives.front().get()) this->DisableWidget(WID_NS_MOVE_UP);
1268 if (this->active_sel == this->actives.back().get()) this->DisableWidget(WID_NS_MOVE_DOWN);
1269 }
1270
1271 this->SetWidgetDisabledState(WID_NS_PRESET_DELETE, this->preset == -1);
1272
1273 bool has_missing = false;
1274 bool has_compatible = false;
1275 for (const auto &c : this->actives) {
1276 has_missing |= c->status == GCS_NOT_FOUND;
1277 has_compatible |= c->flags.Test(GRFConfigFlag::Compatible);
1278 }
1279 StringID text;
1280 StringID tool_tip;
1281 if (has_missing || has_compatible) {
1282 text = STR_NEWGRF_SETTINGS_FIND_MISSING_CONTENT_BUTTON;
1283 tool_tip = STR_NEWGRF_SETTINGS_FIND_MISSING_CONTENT_TOOLTIP;
1284 } else {
1285 text = STR_INTRO_ONLINE_CONTENT;
1286 tool_tip = STR_INTRO_TOOLTIP_ONLINE_CONTENT;
1287 }
1288 this->GetWidget<NWidgetCore>(WID_NS_CONTENT_DOWNLOAD)->SetStringTip(text, tool_tip);
1289 this->GetWidget<NWidgetCore>(WID_NS_CONTENT_DOWNLOAD2)->SetStringTip(text, tool_tip);
1290
1291 this->SetWidgetDisabledState(WID_NS_PRESET_SAVE, has_missing);
1292 }
1293
1294 EventState OnKeyPress([[maybe_unused]] char32_t key, uint16_t keycode) override
1295 {
1296 if (!this->editable) return ES_NOT_HANDLED;
1297
1298 if (this->vscroll2->UpdateListPositionOnKeyPress(this->avail_pos, keycode) == ES_NOT_HANDLED) return ES_NOT_HANDLED;
1299
1300 if (this->avail_pos >= 0) {
1301 this->active_sel = nullptr;
1302 CloseWindowByClass(WC_GRF_PARAMETERS);
1303 if (this->avail_sel != this->avails[this->avail_pos]) this->CloseChildWindows(WC_TEXTFILE);
1304 this->avail_sel = this->avails[this->avail_pos];
1305 this->vscroll2->ScrollTowards(this->avail_pos);
1306 this->InvalidateData(0);
1307 }
1308
1309 return ES_HANDLED;
1310 }
1311
1312 void OnEditboxChanged(WidgetID widget) override
1313 {
1314 if (!this->editable) return;
1315
1316 if (widget == WID_NS_FILTER) {
1317 string_filter.SetFilterTerm(this->filter_editbox.text.GetText());
1318 this->avails.SetFilterState(!string_filter.IsEmpty());
1319 this->avails.ForceRebuild();
1320 this->InvalidateData(0);
1321 }
1322 }
1323
1324 void OnDragDrop(Point pt, WidgetID widget) override
1325 {
1326 if (!this->editable) return;
1327
1328 if (widget == WID_NS_FILE_LIST) {
1329 if (this->active_sel != nullptr) {
1330 int from_pos = this->GetCurrentActivePosition();
1331
1332 /* Gets the drag-and-drop destination offset. Ignore the last dummy line. */
1333 int to_pos = std::min(this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_NS_FILE_LIST, WidgetDimensions::scaled.framerect.top), this->vscroll->GetCount() - 2);
1334 if (to_pos != from_pos) { // Don't move NewGRF file over itself.
1335 if (to_pos > from_pos) ++to_pos;
1336
1337 auto from = std::next(std::begin(this->actives), from_pos);
1338 auto to = std::next(std::begin(this->actives), to_pos);
1339 Slide(from, std::next(from), to);
1340
1341 this->vscroll->ScrollTowards(to_pos);
1342 this->preset = -1;
1343 this->InvalidateData();
1344 }
1345 } else if (this->avail_sel != nullptr) {
1346 int to_pos = std::min(this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_NS_FILE_LIST, WidgetDimensions::scaled.framerect.top), this->vscroll->GetCount() - 1);
1347 this->AddGRFToActive(to_pos);
1348 }
1349 } else if (widget == WID_NS_AVAIL_LIST && this->active_sel != nullptr) {
1350 /* Remove active NewGRF file by dragging it over available list. */
1351 Point dummy = {-1, -1};
1352 this->OnClick(dummy, WID_NS_REMOVE, 1);
1353 }
1354
1355 ResetObjectToPlace();
1356
1357 if (this->active_over != -1) {
1358 /* End of drag-and-drop, hide dragged destination highlight. */
1359 this->SetWidgetDirty(this->active_over == -2 ? WID_NS_AVAIL_LIST : WID_NS_FILE_LIST);
1360 this->active_over = -1;
1361 }
1362 }
1363
1364 void OnMouseDrag(Point pt, WidgetID widget) override
1365 {
1366 if (!this->editable) return;
1367
1368 if (widget == WID_NS_FILE_LIST && (this->active_sel != nullptr || this->avail_sel != nullptr)) {
1369 /* An NewGRF file is dragged over the active list. */
1370 int to_pos = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_NS_FILE_LIST, WidgetDimensions::scaled.framerect.top);
1371 /* Skip the last dummy line if the source is from the active list. */
1372 to_pos = std::min(to_pos, this->vscroll->GetCount() - (this->active_sel != nullptr ? 2 : 1));
1373
1374 if (to_pos != this->active_over) {
1375 this->active_over = to_pos;
1376 this->SetWidgetDirty(WID_NS_FILE_LIST);
1377 }
1378 } else if (widget == WID_NS_AVAIL_LIST && this->active_sel != nullptr) {
1379 this->active_over = -2;
1380 this->SetWidgetDirty(WID_NS_AVAIL_LIST);
1381 } else if (this->active_over != -1) {
1382 this->SetWidgetDirty(this->active_over == -2 ? WID_NS_AVAIL_LIST : WID_NS_FILE_LIST);
1383 this->active_over = -1;
1384 }
1385 }
1386
1387private:
1389 static bool NameSorter(const GRFConfig * const &a, const GRFConfig * const &b)
1390 {
1391 std::string name_a = StrMakeValid(a->GetName(), {}); // Make a copy without control codes.
1392 std::string name_b = StrMakeValid(b->GetName(), {}); // Make a copy without control codes.
1393 int i = StrNaturalCompare(name_a, name_b, true); // Sort by name (natural sorting).
1394 if (i != 0) return i < 0;
1395
1396 i = a->version - b->version;
1397 if (i != 0) return i < 0;
1398
1399 return a->ident.md5sum < b->ident.md5sum;
1400 }
1401
1403 static bool TagNameFilter(const GRFConfig * const *a, StringFilter &filter)
1404 {
1405 filter.ResetState();
1406 filter.AddLine((*a)->GetName());
1407 filter.AddLine((*a)->filename);
1408 if (auto desc = (*a)->GetDescription(); desc.has_value()) filter.AddLine(*desc);
1409 return filter.GetState();;
1410 }
1411
1412 void BuildAvailables()
1413 {
1414 if (!this->avails.NeedRebuild()) return;
1415
1416 this->avails.clear();
1417
1418 for (const auto &c : _all_grfs) {
1419 if (std::ranges::any_of(this->actives, [&c](const auto &gc) { return gc->ident.HasGrfIdentifier(c->ident.grfid, &c->ident.md5sum); })) continue;
1420
1421 if (_settings_client.gui.newgrf_show_old_versions) {
1422 this->avails.push_back(c.get());
1423 } else {
1424 const GRFConfig *best = FindGRFConfig(c->ident.grfid, c->flags.Test(GRFConfigFlag::Invalid) ? FGCM_NEWEST : FGCM_NEWEST_VALID);
1425 /* Never triggers; FindGRFConfig returns either c, or a newer version of c. */
1426 assert(best != nullptr);
1427
1428 /*
1429 * If the best version is 0, then all NewGRF with this GRF ID
1430 * have version 0, so for backward compatibility reasons we
1431 * want to show them all.
1432 * If we are the best version, then we definitely want to
1433 * show that NewGRF!.
1434 */
1435 if (best->version == 0 || best->ident.HasGrfIdentifier(c->ident.grfid, &c->ident.md5sum)) {
1436 this->avails.push_back(c.get());
1437 }
1438 }
1439 }
1440
1441 this->avails.Filter(this->string_filter);
1442 this->avails.RebuildDone();
1443 this->avails.Sort();
1444
1445 if (this->avail_sel != nullptr) {
1446 this->avail_pos = find_index(this->avails, this->avail_sel);
1447 if (this->avail_pos == -1) {
1448 this->avail_sel = nullptr;
1449 }
1450 }
1451
1452 this->vscroll2->SetCount(this->avails.size()); // Update the scrollbar
1453 }
1454
1460 bool AddGRFToActive(int ins_pos = -1)
1461 {
1462 if (this->avail_sel == nullptr || !this->editable || this->avail_sel->flags.Test(GRFConfigFlag::Invalid)) return false;
1463
1464 this->CloseChildWindows(WC_TEXTFILE);
1465
1466 /* Get number of non-static NewGRFs. */
1467 size_t count = std::ranges::count_if(this->actives, [](const auto &gc) { return !gc->flags.Test(GRFConfigFlag::Static); });
1468 if (count >= NETWORK_MAX_GRF_COUNT) {
1469 ShowErrorMessage(GetEncodedString(STR_NEWGRF_TOO_MANY_NEWGRFS), {}, WL_INFO);
1470 return false;
1471 }
1472
1473 /* Check for duplicate GRF ID. */
1474 if (std::ranges::any_of(this->actives, [&grfid = this->avail_sel->ident.grfid](const auto &gc) { return gc->ident.grfid == grfid; })) {
1475 ShowErrorMessage(GetEncodedString(STR_NEWGRF_DUPLICATE_GRFID), {}, WL_INFO);
1476 return false;
1477 }
1478
1479 auto entry = (ins_pos >= 0 && static_cast<size_t>(ins_pos) < std::size(this->actives))
1480 ? std::next(std::begin(this->actives), ins_pos)
1481 : std::end(this->actives);
1482
1483 /* Copy GRF details from scanned list. */
1484 entry = this->actives.insert(entry, std::make_unique<GRFConfig>(*this->avail_sel));
1485 (*entry)->SetParameterDefaults();
1486
1487 /* Select next (or previous, if last one) item in the list. */
1488 int new_pos = this->avail_pos + 1;
1489 if (new_pos >= (int)this->avails.size()) new_pos = this->avail_pos - 1;
1490 this->avail_pos = new_pos;
1491 if (new_pos >= 0) this->avail_sel = this->avails[new_pos];
1492
1493 this->avails.ForceRebuild();
1494 this->InvalidateData(GOID_NEWGRF_LIST_EDITED);
1495 return true;
1496 }
1497};
1498
1503 void ShowMissingContentWindow(const GRFConfigList &list)
1504{
1505 /* Only show the things in the current list, or everything when nothing's selected */
1506 ContentVector cv;
1507 for (const auto &c : list) {
1508 if (c->status != GCS_NOT_FOUND && !c->flags.Test(GRFConfigFlag::Compatible)) continue;
1509
1510 auto ci = std::make_unique<ContentInfo>();
1511 ci->type = CONTENT_TYPE_NEWGRF;
1512 ci->state = ContentInfo::State::DoesNotExist;
1513 ci->name = c->GetName();
1514 ci->unique_id = std::byteswap(c->ident.grfid);
1515 ci->md5sum = c->flags.Test(GRFConfigFlag::Compatible) ? c->original_md5sum : c->ident.md5sum;
1516 cv.push_back(std::move(ci));
1517 }
1518 ShowNetworkContentListWindow(cv.empty() ? nullptr : &cv, CONTENT_TYPE_NEWGRF);
1519}
1520
1521 Listing NewGRFWindow::last_sorting = {false, 0};
1522 Filtering NewGRFWindow::last_filtering = {false, 0};
1523
1524 const std::initializer_list<NewGRFWindow::GUIGRFConfigList::SortFunction * const> NewGRFWindow::sorter_funcs = {
1525 &NameSorter,
1526};
1527
1528 const std::initializer_list<NewGRFWindow::GUIGRFConfigList::FilterFunction * const> NewGRFWindow::filter_funcs = {
1529 &TagNameFilter,
1530};
1531
1538 class NWidgetNewGRFDisplay : public NWidgetBase {
1539public:
1540 static const uint MAX_EXTRA_INFO_WIDTH;
1541 static const uint MIN_EXTRA_FOR_3_COLUMNS;
1542
1543 std::unique_ptr<NWidgetBase> avs{};
1544 std::unique_ptr<NWidgetBase> acs{};
1545 std::unique_ptr<NWidgetBase> inf{};
1546 bool editable = true;
1547
1548 NWidgetNewGRFDisplay(std::unique_ptr<NWidgetBase> &&avs, std::unique_ptr<NWidgetBase> &&acs, std::unique_ptr<NWidgetBase> &&inf) : NWidgetBase(NWID_CUSTOM)
1549 , avs(std::move(avs))
1550 , acs(std::move(acs))
1551 , inf(std::move(inf))
1552 {
1553 }
1554
1555 void SetupSmallestSize(Window *w) override
1556 {
1557 /* Copy state flag from the window. */
1558 assert(dynamic_cast<NewGRFWindow *>(w) != nullptr);
1559 NewGRFWindow *ngw = (NewGRFWindow *)w;
1560 this->editable = ngw->editable;
1561
1562 this->avs->SetupSmallestSize(w);
1563 this->acs->SetupSmallestSize(w);
1564 this->inf->SetupSmallestSize(w);
1565
1566 uint min_avs_width = this->avs->smallest_x + this->avs->padding.Horizontal();
1567 uint min_acs_width = this->acs->smallest_x + this->acs->padding.Horizontal();
1568 uint min_inf_width = this->inf->smallest_x + this->inf->padding.Horizontal();
1569
1570 uint min_avs_height = this->avs->smallest_y + this->avs->padding.Vertical();
1571 uint min_acs_height = this->acs->smallest_y + this->acs->padding.Vertical();
1572 uint min_inf_height = this->inf->smallest_y + this->inf->padding.Vertical();
1573
1574 /* Smallest window is in two column mode. */
1575 this->smallest_x = std::max(min_avs_width, min_acs_width) + WidgetDimensions::scaled.hsep_wide + min_inf_width;
1576 this->smallest_y = std::max(min_inf_height, min_acs_height + WidgetDimensions::scaled.vsep_wide + min_avs_height);
1577
1578 /* Filling. */
1579 this->fill_x = std::lcm(this->avs->fill_x, this->acs->fill_x);
1580 if (this->inf->fill_x > 0 && (this->fill_x == 0 || this->fill_x > this->inf->fill_x)) this->fill_x = this->inf->fill_x;
1581
1582 this->fill_y = this->avs->fill_y;
1583 if (this->acs->fill_y > 0 && (this->fill_y == 0 || this->fill_y > this->acs->fill_y)) this->fill_y = this->acs->fill_y;
1584 this->fill_y = std::lcm(this->fill_y, this->inf->fill_y);
1585
1586 /* Resizing. */
1587 this->resize_x = std::lcm(this->avs->resize_x, this->acs->resize_x);
1588 if (this->inf->resize_x > 0 && (this->resize_x == 0 || this->resize_x > this->inf->resize_x)) this->resize_x = this->inf->resize_x;
1589
1590 this->resize_y = this->avs->resize_y;
1591 if (this->acs->resize_y > 0 && (this->resize_y == 0 || this->resize_y > this->acs->resize_y)) this->resize_y = this->acs->resize_y;
1592 this->resize_y = std::lcm(this->resize_y, this->inf->resize_y);
1593
1594 /* Make sure the height suits the 3 column (resp. not-editable) format; the 2 column format can easily fill space between the lists */
1595 this->smallest_y = ComputeMaxSize(min_acs_height, this->smallest_y + this->resize_y - 1, this->resize_y);
1596 }
1597
1598 void AssignSizePosition(SizingType sizing, int x, int y, uint given_width, uint given_height, bool rtl) override
1599 {
1600 this->StoreSizePosition(sizing, x, y, given_width, given_height);
1601
1602 uint min_avs_width = this->avs->smallest_x + this->avs->padding.Horizontal();
1603 uint min_acs_width = this->acs->smallest_x + this->acs->padding.Horizontal();
1604 uint min_inf_width = this->inf->smallest_x + this->inf->padding.Horizontal();
1605
1606 uint min_list_width = std::max(min_avs_width, min_acs_width); // Smallest width of the lists such that they have equal width (incl padding).
1607 uint avs_extra_width = min_list_width - min_avs_width; // Additional width needed for avs to reach min_list_width.
1608 uint acs_extra_width = min_list_width - min_acs_width; // Additional width needed for acs to reach min_list_width.
1609
1610 /* Use 2 or 3 columns? */
1611 uint min_three_columns = min_avs_width + min_acs_width + min_inf_width + 2 * WidgetDimensions::scaled.hsep_wide;
1612 uint min_two_columns = min_list_width + min_inf_width + WidgetDimensions::scaled.hsep_wide;
1613 bool use_three_columns = this->editable && (min_three_columns + ScaleGUITrad(MIN_EXTRA_FOR_3_COLUMNS) <= given_width);
1614
1615 /* Info panel is a separate column in both modes. Compute its width first. */
1616 uint extra_width, inf_width;
1617 if (use_three_columns) {
1618 extra_width = given_width - min_three_columns;
1619 inf_width = std::min<uint>(ScaleGUITrad(MAX_EXTRA_INFO_WIDTH), extra_width / 2);
1620 } else {
1621 extra_width = given_width - min_two_columns;
1622 inf_width = std::min<uint>(ScaleGUITrad(MAX_EXTRA_INFO_WIDTH), extra_width / 2);
1623 }
1624 inf_width = ComputeMaxSize(this->inf->smallest_x, this->inf->smallest_x + inf_width, this->inf->GetHorizontalStepSize(sizing));
1625 extra_width -= inf_width - this->inf->smallest_x;
1626
1627 uint inf_height = ComputeMaxSize(this->inf->smallest_y, given_height, this->inf->GetVerticalStepSize(sizing));
1628
1629 if (use_three_columns) {
1630 /* Three column display, first make both lists equally wide, then divide whatever is left between both lists.
1631 * Only keep track of what avs gets, all other space goes to acs. */
1632 uint avs_width = std::min(avs_extra_width, extra_width);
1633 extra_width -= avs_width;
1634 extra_width -= std::min(acs_extra_width, extra_width);
1635 avs_width += extra_width / 2;
1636
1637 avs_width = ComputeMaxSize(this->avs->smallest_x, this->avs->smallest_x + avs_width, this->avs->GetHorizontalStepSize(sizing));
1638
1639 uint acs_width = given_width - // Remaining space, including horizontal padding.
1640 inf_width - this->inf->padding.Horizontal() -
1641 avs_width - this->avs->padding.Horizontal() - 2 * WidgetDimensions::scaled.hsep_wide;
1642 acs_width = ComputeMaxSize(min_acs_width, acs_width, this->acs->GetHorizontalStepSize(sizing)) -
1643 this->acs->padding.Horizontal();
1644
1645 /* Never use fill_y on these; the minimal size is chosen, so that the 3 column view looks nice */
1646 uint avs_height = ComputeMaxSize(this->avs->smallest_y, given_height, this->avs->resize_y);
1647 uint acs_height = ComputeMaxSize(this->acs->smallest_y, given_height, this->acs->resize_y);
1648
1649 /* Assign size and position to the children. */
1650 if (rtl) {
1651 x += this->inf->padding.left;
1652 this->inf->AssignSizePosition(sizing, x, y + this->inf->padding.top, inf_width, inf_height, rtl);
1653 x += inf_width + this->inf->padding.right + WidgetDimensions::scaled.hsep_wide;
1654 } else {
1655 x += this->avs->padding.left;
1656 this->avs->AssignSizePosition(sizing, x, y + this->avs->padding.top, avs_width, avs_height, rtl);
1657 x += avs_width + this->avs->padding.right + WidgetDimensions::scaled.hsep_wide;
1658 }
1659
1660 x += this->acs->padding.left;
1661 this->acs->AssignSizePosition(sizing, x, y + this->acs->padding.top, acs_width, acs_height, rtl);
1662 x += acs_width + this->acs->padding.right + WidgetDimensions::scaled.hsep_wide;
1663
1664 if (rtl) {
1665 x += this->avs->padding.left;
1666 this->avs->AssignSizePosition(sizing, x, y + this->avs->padding.top, avs_width, avs_height, rtl);
1667 } else {
1668 x += this->inf->padding.left;
1669 this->inf->AssignSizePosition(sizing, x, y + this->inf->padding.top, inf_width, inf_height, rtl);
1670 }
1671 } else {
1672 /* Two columns, all space in extra_width goes to both lists. Since the lists are underneath each other,
1673 * the column is min_list_width wide at least. */
1674 uint avs_width = ComputeMaxSize(this->avs->smallest_x, this->avs->smallest_x + avs_extra_width + extra_width,
1675 this->avs->GetHorizontalStepSize(sizing));
1676 uint acs_width = ComputeMaxSize(this->acs->smallest_x, this->acs->smallest_x + acs_extra_width + extra_width,
1677 this->acs->GetHorizontalStepSize(sizing));
1678
1679 uint min_avs_height = (!this->editable) ? 0 : this->avs->smallest_y + this->avs->padding.Vertical() + WidgetDimensions::scaled.vsep_wide;
1680 uint min_acs_height = this->acs->smallest_y + this->acs->padding.Vertical();
1681 uint extra_height = given_height - min_acs_height - min_avs_height;
1682
1683 /* Never use fill_y on these; instead use WidgetDimensions::scaled.vsep_wide as filler */
1684 uint avs_height = ComputeMaxSize(this->avs->smallest_y, this->avs->smallest_y + extra_height / 2, this->avs->resize_y);
1685 if (this->editable) extra_height -= avs_height - this->avs->smallest_y;
1686 uint acs_height = ComputeMaxSize(this->acs->smallest_y, this->acs->smallest_y + extra_height, this->acs->resize_y);
1687
1688 /* Assign size and position to the children. */
1689 if (rtl) {
1690 x += this->inf->padding.left;
1691 this->inf->AssignSizePosition(sizing, x, y + this->inf->padding.top, inf_width, inf_height, rtl);
1692 x += inf_width + this->inf->padding.right + WidgetDimensions::scaled.hsep_wide;
1693
1694 this->acs->AssignSizePosition(sizing, x + this->acs->padding.left, y + this->acs->padding.top, acs_width, acs_height, rtl);
1695 if (this->editable) {
1696 this->avs->AssignSizePosition(sizing, x + this->avs->padding.left, y + given_height - avs_height - this->avs->padding.bottom, avs_width, avs_height, rtl);
1697 } else {
1698 this->avs->AssignSizePosition(sizing, 0, 0, this->avs->smallest_x, this->avs->smallest_y, rtl);
1699 }
1700 } else {
1701 this->acs->AssignSizePosition(sizing, x + this->acs->padding.left, y + this->acs->padding.top, acs_width, acs_height, rtl);
1702 if (this->editable) {
1703 this->avs->AssignSizePosition(sizing, x + this->avs->padding.left, y + given_height - avs_height - this->avs->padding.bottom, avs_width, avs_height, rtl);
1704 } else {
1705 this->avs->AssignSizePosition(sizing, 0, 0, this->avs->smallest_x, this->avs->smallest_y, rtl);
1706 }
1707 uint dx = this->acs->current_x + this->acs->padding.Horizontal();
1708 if (this->editable) {
1709 dx = std::max(dx, this->avs->current_x + this->avs->padding.Horizontal());
1710 }
1711 x += dx + WidgetDimensions::scaled.hsep_wide + this->inf->padding.left;
1712 this->inf->AssignSizePosition(sizing, x, y + this->inf->padding.top, inf_width, inf_height, rtl);
1713 }
1714 }
1715 }
1716
1717 void FillWidgetLookup(WidgetLookup &widget_lookup) override
1718 {
1719 this->NWidgetBase::FillWidgetLookup(widget_lookup);
1720 this->avs->FillWidgetLookup(widget_lookup);
1721 this->acs->FillWidgetLookup(widget_lookup);
1722 this->inf->FillWidgetLookup(widget_lookup);
1723 }
1724
1725 NWidgetCore *GetWidgetFromPos(int x, int y) override
1726 {
1727 if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return nullptr;
1728
1729 NWidgetCore *nw = (this->editable) ? this->avs->GetWidgetFromPos(x, y) : nullptr;
1730 if (nw == nullptr) nw = this->acs->GetWidgetFromPos(x, y);
1731 if (nw == nullptr) nw = this->inf->GetWidgetFromPos(x, y);
1732 return nw;
1733 }
1734
1735 void Draw(const Window *w) override
1736 {
1737 if (this->editable) this->avs->Draw(w);
1738 this->acs->Draw(w);
1739 this->inf->Draw(w);
1740 }
1741};
1742
1743const uint NWidgetNewGRFDisplay::MAX_EXTRA_INFO_WIDTH = 150;
1744const uint NWidgetNewGRFDisplay::MIN_EXTRA_FOR_3_COLUMNS = 50;
1745
1746static constexpr std::initializer_list<NWidgetPart> _nested_newgrf_actives_widgets = {
1747 NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0),
1748 /* Left side, presets. */
1749 NWidget(NWID_VERTICAL),
1750 NWidget(NWID_HORIZONTAL),
1751 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_NEWGRF_SETTINGS_SELECT_PRESET),
1752 SetPadding(0, WidgetDimensions::unscaled.hsep_wide, 0, 0),
1753 NWidget(WWT_DROPDOWN, COLOUR_YELLOW, WID_NS_PRESET_LIST), SetFill(1, 0), SetResize(1, 0),
1754 SetToolTip(STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP),
1755 EndContainer(),
1756 NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
1757 NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_PRESET_SAVE), SetFill(1, 0), SetResize(1, 0),
1758 SetStringTip(STR_NEWGRF_SETTINGS_PRESET_SAVE, STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP),
1759 NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_PRESET_DELETE), SetFill(1, 0), SetResize(1, 0),
1760 SetStringTip(STR_NEWGRF_SETTINGS_PRESET_DELETE, STR_NEWGRF_SETTINGS_PRESET_DELETE_TOOLTIP),
1761 EndContainer(),
1762 EndContainer(),
1763
1764 NWidget(WWT_FRAME, COLOUR_MAUVE), SetStringTip(STR_NEWGRF_SETTINGS_ACTIVE_LIST), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0),
1765 /* Left side, active grfs. */
1766 NWidget(NWID_HORIZONTAL),
1767 NWidget(WWT_PANEL, COLOUR_MAUVE),
1768 NWidget(WWT_INSET, COLOUR_MAUVE, WID_NS_FILE_LIST), SetMinimalSize(100, 1), SetPadding(2),
1769 SetFill(1, 1), SetResize(1, 1), SetScrollbar(WID_NS_SCROLLBAR), SetToolTip(STR_NEWGRF_SETTINGS_FILE_TOOLTIP),
1770 EndContainer(),
1771 EndContainer(),
1772 NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, WID_NS_SCROLLBAR),
1773 EndContainer(),
1774
1775 /* Buttons. */
1776 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NS_SHOW_REMOVE),
1777 NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0),
1778 NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_REMOVE), SetFill(1, 0), SetResize(1, 0),
1779 SetStringTip(STR_NEWGRF_SETTINGS_REMOVE, STR_NEWGRF_SETTINGS_REMOVE_TOOLTIP),
1780 NWidget(NWID_VERTICAL),
1781 NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_MOVE_UP), SetFill(1, 0), SetResize(1, 0),
1782 SetStringTip(STR_NEWGRF_SETTINGS_MOVEUP, STR_NEWGRF_SETTINGS_MOVEUP_TOOLTIP),
1783 NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_MOVE_DOWN), SetFill(1, 0), SetResize(1, 0),
1784 SetStringTip(STR_NEWGRF_SETTINGS_MOVEDOWN, STR_NEWGRF_SETTINGS_MOVEDOWN_TOOLTIP),
1785 EndContainer(),
1786 NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_UPGRADE), SetFill(1, 0), SetResize(1, 0),
1787 SetStringTip(STR_NEWGRF_SETTINGS_UPGRADE, STR_NEWGRF_SETTINGS_UPGRADE_TOOLTIP),
1788 EndContainer(),
1789
1790 NWidget(NWID_VERTICAL, NWidContainerFlag::EqualSize),
1791 NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_RESCAN_FILES2), SetFill(1, 0), SetResize(1, 0),
1792 SetStringTip(STR_NEWGRF_SETTINGS_RESCAN_FILES, STR_NEWGRF_SETTINGS_RESCAN_FILES_TOOLTIP),
1793 NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_CONTENT_DOWNLOAD2), SetFill(1, 0), SetResize(1, 0),
1794 SetStringTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT),
1795 EndContainer(),
1796 EndContainer(),
1797 EndContainer(),
1798 EndContainer(),
1799};
1800
1801static constexpr std::initializer_list<NWidgetPart> _nested_newgrf_availables_widgets = {
1802 NWidget(WWT_FRAME, COLOUR_MAUVE), SetStringTip(STR_NEWGRF_SETTINGS_INACTIVE_LIST), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0),
1803 /* Left side, available grfs, filter edit box. */
1804 NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0),
1805 NWidget(WWT_TEXT, INVALID_COLOUR), SetFill(0, 1), SetStringTip(STR_NEWGRF_FILTER_TITLE),
1806 NWidget(WWT_EDITBOX, COLOUR_MAUVE, WID_NS_FILTER), SetFill(1, 0), SetResize(1, 0),
1807 SetStringTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
1808 EndContainer(),
1809
1810 /* Left side, available grfs. */
1811 NWidget(NWID_HORIZONTAL),
1812 NWidget(WWT_PANEL, COLOUR_MAUVE),
1813 NWidget(WWT_INSET, COLOUR_MAUVE, WID_NS_AVAIL_LIST), SetMinimalSize(100, 1), SetPadding(2),
1814 SetFill(1, 1), SetResize(1, 1), SetScrollbar(WID_NS_SCROLL2BAR),
1815 EndContainer(),
1816 EndContainer(),
1817 NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, WID_NS_SCROLL2BAR),
1818 EndContainer(),
1819
1820 /* Left side, available grfs, buttons. */
1821 NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0),
1822 NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_ADD), SetFill(1, 0), SetResize(1, 0),
1823 SetStringTip(STR_NEWGRF_SETTINGS_ADD, STR_NEWGRF_SETTINGS_ADD_FILE_TOOLTIP),
1824 NWidget(NWID_VERTICAL),
1825 NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_RESCAN_FILES), SetFill(1, 0), SetResize(1, 0),
1826 SetStringTip(STR_NEWGRF_SETTINGS_RESCAN_FILES, STR_NEWGRF_SETTINGS_RESCAN_FILES_TOOLTIP),
1827 NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_CONTENT_DOWNLOAD), SetFill(1, 0), SetResize(1, 0),
1828 SetStringTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT),
1829 EndContainer(),
1830 EndContainer(),
1831 EndContainer(),
1832};
1833
1834static constexpr std::initializer_list<NWidgetPart> _nested_newgrf_infopanel_widgets = {
1835 NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0),
1836 /* Right side, info panel. */
1837 NWidget(WWT_PANEL, COLOUR_MAUVE),
1838 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_NS_NEWGRF_INFO_TITLE), SetFill(1, 0), SetResize(1, 0),
1839 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_NS_NEWGRF_INFO), SetFill(1, 1), SetResize(1, 1), SetMinimalSize(150, 100),
1840 EndContainer(),
1841
1842 /* Right side, info buttons. */
1843 NWidget(NWID_VERTICAL),
1844 NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
1845 NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_OPEN_URL), SetFill(1, 0), SetResize(1, 0),
1846 SetStringTip(STR_CONTENT_OPEN_URL, STR_CONTENT_OPEN_URL_TOOLTIP),
1847 NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_NEWGRF_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0),
1848 SetStringTip(STR_TEXTFILE_VIEW_README, STR_TEXTFILE_VIEW_README_TOOLTIP),
1849 EndContainer(),
1850 NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
1851 NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_NEWGRF_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0),
1852 SetStringTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_TEXTFILE_VIEW_CHANGELOG_TOOLTIP),
1853 NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_NEWGRF_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0),
1854 SetStringTip(STR_TEXTFILE_VIEW_LICENCE, STR_TEXTFILE_VIEW_LICENCE_TOOLTIP),
1855 EndContainer(),
1856 EndContainer(),
1857
1858 /* Right side, config buttons. */
1859 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NS_SHOW_EDIT),
1860 NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0),
1861 NWidget(NWID_VERTICAL),
1862 NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_SET_PARAMETERS), SetFill(1, 0), SetResize(1, 0),
1863 SetStringTip(STR_NEWGRF_SETTINGS_SET_PARAMETERS),
1864 NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_TOGGLE_PALETTE), SetFill(1, 0), SetResize(1, 0),
1865 SetStringTip(STR_NEWGRF_SETTINGS_TOGGLE_PALETTE, STR_NEWGRF_SETTINGS_TOGGLE_PALETTE_TOOLTIP),
1866 EndContainer(),
1867 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NS_SHOW_APPLY),
1868 NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_APPLY_CHANGES), SetFill(1, 0), SetResize(1, 0),
1869 SetStringTip(STR_NEWGRF_SETTINGS_APPLY_CHANGES),
1870 EndContainer(),
1871 EndContainer(),
1872 NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_VIEW_PARAMETERS), SetFill(1, 0), SetResize(1, 0),
1873 SetStringTip(STR_NEWGRF_SETTINGS_SHOW_PARAMETERS),
1874 EndContainer(),
1875 EndContainer(),
1876};
1877
1879std::unique_ptr<NWidgetBase> NewGRFDisplay()
1880{
1881 std::unique_ptr<NWidgetBase> avs = MakeNWidgets(_nested_newgrf_availables_widgets, nullptr);
1882 std::unique_ptr<NWidgetBase> acs = MakeNWidgets(_nested_newgrf_actives_widgets, nullptr);
1883 std::unique_ptr<NWidgetBase> inf = MakeNWidgets(_nested_newgrf_infopanel_widgets, nullptr);
1884
1885 return std::make_unique<NWidgetNewGRFDisplay>(std::move(avs), std::move(acs), std::move(inf));
1886}
1887
1888/* Widget definition of the manage newgrfs window */
1889static constexpr std::initializer_list<NWidgetPart> _nested_newgrf_widgets = {
1890 NWidget(NWID_HORIZONTAL),
1891 NWidget(WWT_CLOSEBOX, COLOUR_MAUVE),
1892 NWidget(WWT_CAPTION, COLOUR_MAUVE), SetStringTip(STR_NEWGRF_SETTINGS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1893 NWidget(WWT_DEFSIZEBOX, COLOUR_MAUVE),
1894 EndContainer(),
1895 NWidget(WWT_PANEL, COLOUR_MAUVE),
1896 NWidgetFunction(NewGRFDisplay), SetPadding(WidgetDimensions::unscaled.sparse_resize),
1897 /* Resize button. */
1898 NWidget(NWID_HORIZONTAL),
1899 NWidget(NWID_SPACER), SetFill(1, 0), SetResize(1, 0),
1900 NWidget(WWT_RESIZEBOX, COLOUR_MAUVE), SetResizeWidgetTypeTip(RWV_HIDE_BEVEL, STR_TOOLTIP_RESIZE),
1901 EndContainer(),
1902 EndContainer(),
1903};
1904
1905/* Window definition of the manage newgrfs window */
1906static WindowDesc _newgrf_desc(
1907 WDP_CENTER, "settings_newgrf", 300, 263,
1908 WC_GAME_OPTIONS, WC_NONE,
1909 {},
1910 _nested_newgrf_widgets
1911);
1912
1918 static void NewGRFConfirmationCallback(Window *w, bool confirmed)
1919{
1920 if (confirmed) {
1921 CloseWindowByClass(WC_GRF_PARAMETERS);
1922 w->CloseChildWindows(WC_TEXTFILE);
1923 NewGRFWindow *nw = dynamic_cast<NewGRFWindow*>(w);
1924 assert(nw != nullptr);
1925
1926 _gamelog.StartAction(GLAT_GRF);
1927 _gamelog.GRFUpdate(_grfconfig, nw->actives); // log GRF changes
1928 CopyGRFConfigList(nw->orig_list, nw->actives, false);
1929 ReloadNewGRFData();
1930 _gamelog.StopAction();
1931
1932 /* Show new, updated list */
1933 int pos = nw->GetCurrentActivePosition();
1934
1935 CopyGRFConfigList(nw->actives, nw->orig_list, false);
1936
1937 if (nw->active_sel != nullptr) {
1938 /* Set current selection from position */
1939 if (static_cast<size_t>(pos) >= nw->actives.size()) {
1940 nw->active_sel = nw->actives.back().get();
1941 } else {
1942 auto it = std::next(std::begin(nw->actives), pos);
1943 nw->active_sel = it->get();
1944 }
1945 }
1946 nw->avails.ForceRebuild();
1947 nw->modified = false;
1948
1949 w->InvalidateData();
1950
1951 ReInitAllWindows(false);
1952 CloseWindowByClass(WC_BUILD_OBJECT);
1953 }
1954}
1955
1956
1957
1966 void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfigList &config)
1967{
1968 CloseWindowByClass(WC_GAME_OPTIONS);
1969 new NewGRFWindow(_newgrf_desc, editable, show_params, exec_changes, config);
1970}
1971
1973 static constexpr std::initializer_list<NWidgetPart> _nested_save_preset_widgets = {
1974 NWidget(NWID_HORIZONTAL),
1975 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
1976 NWidget(WWT_CAPTION, COLOUR_GREY), SetStringTip(STR_SAVE_PRESET_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1977 NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
1978 EndContainer(),
1979 NWidget(WWT_PANEL, COLOUR_GREY),
1980 NWidget(NWID_HORIZONTAL),
1981 NWidget(WWT_INSET, COLOUR_GREY, WID_SVP_PRESET_LIST), SetPadding(2, 1, 2, 2),
1982 SetToolTip(STR_SAVE_PRESET_LIST_TOOLTIP), SetResize(1, 10), SetScrollbar(WID_SVP_SCROLLBAR), EndContainer(),
1983 NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SVP_SCROLLBAR),
1984 EndContainer(),
1985 EndContainer(),
1986 NWidget(WWT_PANEL, COLOUR_GREY),
1987 NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SVP_EDITBOX), SetPadding(2, 2, 2, 2), SetFill(1, 0), SetResize(1, 0),
1988 SetStringTip(STR_SAVE_PRESET_TITLE, STR_SAVE_PRESET_EDITBOX_TOOLTIP),
1989 EndContainer(),
1990 NWidget(NWID_HORIZONTAL),
1991 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SVP_SAVE), SetStringTip(STR_SAVE_PRESET_SAVE, STR_SAVE_PRESET_SAVE_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
1992 NWidget(WWT_RESIZEBOX, COLOUR_GREY),
1993 EndContainer(),
1994};
1995
1997 static WindowDesc _save_preset_desc(
1998 WDP_CENTER, "save_preset", 140, 110,
1999 WC_SAVE_PRESET, WC_GAME_OPTIONS,
2000 WindowDefaultFlag::Modal,
2001 _nested_save_preset_widgets
2002);
2003
2005 struct SavePresetWindow : public Window {
2006 QueryString presetname_editbox;
2007 StringList presets{};
2008 Scrollbar *vscroll = nullptr;
2009 int selected = -1;
2010
2015 SavePresetWindow(std::string_view initial_text) : Window(_save_preset_desc), presetname_editbox(32)
2016 {
2017 this->presets = GetGRFPresetList();
2018 if (!initial_text.empty()) {
2019 for (uint i = 0; i < this->presets.size(); i++) {
2020 if (this->presets[i] == initial_text) {
2021 this->selected = i;
2022 break;
2023 }
2024 }
2025 }
2026
2027 this->querystrings[WID_SVP_EDITBOX] = &this->presetname_editbox;
2028 this->presetname_editbox.ok_button = WID_SVP_SAVE;
2029
2030 this->CreateNestedTree();
2031 this->vscroll = this->GetScrollbar(WID_SVP_SCROLLBAR);
2032 this->FinishInitNested(0);
2033
2034 this->vscroll->SetCount(this->presets.size());
2035 this->SetFocusedWidget(WID_SVP_EDITBOX);
2036 this->presetname_editbox.text.Assign(initial_text);
2037 }
2038
2039 ~SavePresetWindow()
2040 {
2041 }
2042
2043 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
2044 {
2045 switch (widget) {
2046 case WID_SVP_PRESET_LIST: {
2047 fill.height = resize.height = GetCharacterHeight(FS_NORMAL);
2048 size.height = 0;
2049 for (uint i = 0; i < this->presets.size(); i++) {
2050 Dimension d = GetStringBoundingBox(this->presets[i]);
2051 size.width = std::max(size.width, d.width + padding.width);
2052 }
2053 size.height = ClampU((uint)this->presets.size(), 5, 20) * resize.height + padding.height;
2054 break;
2055 }
2056 }
2057 }
2058
2059 void DrawWidget(const Rect &r, WidgetID widget) const override
2060 {
2061 switch (widget) {
2062 case WID_SVP_PRESET_LIST: {
2063 const Rect br = r.Shrink(WidgetDimensions::scaled.bevel);
2064 GfxFillRect(br, PC_BLACK);
2065
2066 uint step_height = this->GetWidget<NWidgetBase>(WID_SVP_PRESET_LIST)->resize_y;
2067 int offset_y = (step_height - GetCharacterHeight(FS_NORMAL)) / 2;
2068 Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
2069
2070 auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->presets);
2071 for (auto it = first; it != last; ++it) {
2072 int row = static_cast<int>(std::distance(std::begin(this->presets), it));
2073 if (row == this->selected) GfxFillRect(br.left, tr.top, br.right, tr.top + step_height - 1, PC_DARK_BLUE);
2074
2075 DrawString(tr.left, tr.right, tr.top + offset_y, *it, (row == this->selected) ? TC_WHITE : TC_SILVER);
2076 tr.top += step_height;
2077 }
2078 break;
2079 }
2080 }
2081 }
2082
2083 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
2084 {
2085 switch (widget) {
2086 case WID_SVP_PRESET_LIST: {
2087 auto it = this->vscroll->GetScrolledItemFromWidget(this->presets, pt.y, this, WID_SVP_PRESET_LIST);
2088 if (it != this->presets.end()) {
2089 this->selected = it - this->presets.begin();
2090 this->presetname_editbox.text.Assign(*it);
2091 this->SetWidgetDirty(WID_SVP_PRESET_LIST);
2092 this->SetWidgetDirty(WID_SVP_EDITBOX);
2093 }
2094 break;
2095 }
2096
2097 case WID_SVP_SAVE: {
2098 Window *w = FindWindowById(WC_GAME_OPTIONS, WN_GAME_OPTIONS_NEWGRF_STATE);
2099 if (w != nullptr) {
2100 auto text = this->presetname_editbox.text.GetText();
2101 if (!text.empty()) w->OnQueryTextFinished(std::string{text});
2102 }
2103 this->Close();
2104 break;
2105 }
2106 }
2107 }
2108
2109 void OnResize() override
2110 {
2111 this->vscroll->SetCapacityFromWidget(this, WID_SVP_PRESET_LIST, WidgetDimensions::scaled.framerect.Vertical());
2112 }
2113};
2114
2119 static void ShowSavePresetWindow(std::string_view initial_text)
2120{
2121 CloseWindowByClass(WC_SAVE_PRESET);
2122 new SavePresetWindow(initial_text);
2123}
2124
2126 static constexpr std::initializer_list<NWidgetPart> _nested_scan_progress_widgets = {
2127 NWidget(WWT_CAPTION, COLOUR_GREY), SetStringTip(STR_NEWGRF_SCAN_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
2128 NWidget(WWT_PANEL, COLOUR_GREY),
2129 NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), SetPadding(WidgetDimensions::unscaled.modalpopup),
2130 NWidget(WWT_LABEL, INVALID_COLOUR), SetStringTip(STR_NEWGRF_SCAN_MESSAGE), SetFill(1, 0),
2131 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SP_PROGRESS_BAR), SetFill(1, 0),
2132 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SP_PROGRESS_TEXT), SetFill(1, 0), SetMinimalSize(400, 0),
2133 EndContainer(),
2134 EndContainer(),
2135};
2136
2138 static WindowDesc _scan_progress_desc(
2139 WDP_CENTER, {}, 0, 0,
2140 WC_MODAL_PROGRESS, WC_NONE,
2141 {},
2142 _nested_scan_progress_widgets
2143);
2144
2146 struct ScanProgressWindow : public Window {
2147 std::string last_name{};
2148 int scanned = 0;
2149
2151 ScanProgressWindow() : Window(_scan_progress_desc)
2152 {
2153 this->InitNested(1);
2154 }
2155
2156 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
2157 {
2158 switch (widget) {
2159 case WID_SP_PROGRESS_BAR:
2160 size = GetStringBoundingBox(GetString(STR_GENERATION_PROGRESS, GetParamMaxValue(100)));
2161 /* We need some spacing for the 'border' */
2162 size.height += WidgetDimensions::scaled.frametext.Horizontal();
2163 size.width += WidgetDimensions::scaled.frametext.Vertical();
2164 break;
2165
2166 case WID_SP_PROGRESS_TEXT: {
2167 uint64_t max_digits = GetParamMaxDigits(4);
2168 /* We really don't know the width. We could determine it by scanning the NewGRFs,
2169 * but this is the status window for scanning them... */
2170 size.width = std::max<uint>(size.width, GetStringBoundingBox(GetString(STR_NEWGRF_SCAN_STATUS, max_digits, max_digits)).width + padding.width);
2171 size.height = GetCharacterHeight(FS_NORMAL) * 2 + WidgetDimensions::scaled.vsep_normal;
2172 break;
2173 }
2174 }
2175 }
2176
2177 void DrawWidget(const Rect &r, WidgetID widget) const override
2178 {
2179 switch (widget) {
2180 case WID_SP_PROGRESS_BAR: {
2181 /* Draw the % complete with a bar and a text */
2182 DrawFrameRect(r, COLOUR_GREY, {FrameFlag::BorderOnly, FrameFlag::Lowered});
2183 Rect ir = r.Shrink(WidgetDimensions::scaled.bevel);
2184 uint percent = scanned * 100 / std::max(1U, _settings_client.gui.last_newgrf_count);
2185 DrawFrameRect(ir.WithWidth(ir.Width() * percent / 100, _current_text_dir == TD_RTL), COLOUR_MAUVE, {});
2186 DrawString(ir.left, ir.right, CentreBounds(ir.top, ir.bottom, GetCharacterHeight(FS_NORMAL)), GetString(STR_GENERATION_PROGRESS, percent), TC_FROMSTRING, SA_HOR_CENTER);
2187 break;
2188 }
2189
2190 case WID_SP_PROGRESS_TEXT:
2191 DrawString(r.left, r.right, r.top, GetString(STR_NEWGRF_SCAN_STATUS, this->scanned, _settings_client.gui.last_newgrf_count), TC_FROMSTRING, SA_HOR_CENTER);
2192
2193 DrawString(r.left, r.right, r.top + GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal, this->last_name, TC_BLACK, SA_HOR_CENTER);
2194 break;
2195 }
2196 }
2197
2203 void UpdateNewGRFScanStatus(uint num, std::string &&name)
2204 {
2205 this->last_name = std::move(name);
2206 this->scanned = num;
2207 if (num > _settings_client.gui.last_newgrf_count) _settings_client.gui.last_newgrf_count = num;
2208
2209 this->SetDirty();
2210 }
2211};
2212
2218 void UpdateNewGRFScanStatus(uint num, std::string &&name)
2219{
2220 ScanProgressWindow *w = dynamic_cast<ScanProgressWindow *>(FindWindowByClass(WC_MODAL_PROGRESS));
2221 if (w == nullptr) w = new ScanProgressWindow();
2222 w->UpdateNewGRFScanStatus(num, std::move(name));
2223}
BaseBitSet::Test
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
Definition base_bitset_type.hpp:141
GUIList
List template of 'things' T to sort in a GUI.
Definition sortlist_type.h:43
GUIList::Filter
bool Filter(FilterFunction *decide, F filter_data)
Filter the list.
Definition sortlist_type.h:342
GUIList::RebuildDone
void RebuildDone()
Notify the sortlist that the rebuild is done.
Definition sortlist_type.h:405
GUIList::SetFiltering
void SetFiltering(Filtering f)
Import filter conditions.
Definition sortlist_type.h:200
GUIList::SetListing
void SetListing(Listing l)
Import sort conditions.
Definition sortlist_type.h:148
GUIList::SetFilterState
void SetFilterState(bool state)
Enable or disable the filter.
Definition sortlist_type.h:326
GUIList::SetFilterFuncs
void SetFilterFuncs(std::span< FilterFunction *const > n_funcs)
Hand the filter function pointers to the GUIList.
Definition sortlist_type.h:365
GUIList::NeedRebuild
bool NeedRebuild() const
Check if a rebuild is needed.
Definition sortlist_type.h:387
GUIList::ForceRebuild
void ForceRebuild()
Force that a rebuild is needed.
Definition sortlist_type.h:395
GUIList::Sort
bool Sort(Comp compare)
Sort the list.
Definition sortlist_type.h:266
GUIList::SetSortFuncs
void SetSortFuncs(std::span< SortFunction *const > n_funcs)
Hand the sort function pointers to the GUIList.
Definition sortlist_type.h:293
Gamelog::StartAction
void StartAction(GamelogActionType at)
Stores information about new action, but doesn't allocate it Action is allocated only when there is a...
Definition gamelog.cpp:65
Gamelog::StopAction
void StopAction()
Stops logging of any changes.
Definition gamelog.cpp:74
Gamelog::GRFUpdate
void GRFUpdate(const GRFConfigList &oldg, const GRFConfigList &newg)
Compares two NewGRF lists and logs any change.
Definition gamelog.cpp:606
NWidgetBase
Baseclass for nested widgets.
Definition widget_type.h:136
NWidgetBase::StoreSizePosition
void StoreSizePosition(SizingType sizing, int x, int y, uint given_width, uint given_height)
Store size and position.
Definition widget_type.h:282
NWidgetBase::resize_x
uint resize_x
Horizontal resize step (0 means not resizable).
Definition widget_type.h:229
NWidgetBase::fill_x
uint fill_x
Horizontal fill stepsize (from initial size, 0 means not resizable).
Definition widget_type.h:227
NWidgetBase::smallest_x
uint smallest_x
Smallest horizontal size of the widget in a filled window.
Definition widget_type.h:234
NWidgetBase::current_x
uint current_x
Current horizontal size (after resizing).
Definition widget_type.h:237
NWidgetBase::pos_y
int pos_y
Vertical position of top-left corner of the widget in the window.
Definition widget_type.h:243
NWidgetBase::pos_x
int pos_x
Horizontal position of top-left corner of the widget in the window.
Definition widget_type.h:242
NWidgetBase::smallest_y
uint smallest_y
Smallest vertical size of the widget in a filled window.
Definition widget_type.h:235
NWidgetBase::fill_y
uint fill_y
Vertical fill stepsize (from initial size, 0 means not resizable).
Definition widget_type.h:228
NWidgetBase::resize_y
uint resize_y
Vertical resize step (0 means not resizable).
Definition widget_type.h:230
NWidgetBase::current_y
uint current_y
Current vertical size (after resizing).
Definition widget_type.h:238
NWidgetBase::FillWidgetLookup
virtual void FillWidgetLookup(WidgetLookup &widget_lookup)
Fill the Window::widget_lookup with pointers to nested widgets in the tree.
Definition widget.cpp:915
NWidgetCore
Base class for a 'real' widget.
Definition widget_type.h:368
NWidgetCore::GetWidgetFromPos
NWidgetCore * GetWidgetFromPos(int x, int y) override
Retrieve a widget by its position.
Definition widget.cpp:1265
NWidgetNewGRFDisplay
Custom nested widget container for the NewGRF gui.
Definition newgrf_gui.cpp:1538
NWidgetNewGRFDisplay::editable
bool editable
Editable status of the parent NewGRF window (if false, drop all widgets that make the window editable...
Definition newgrf_gui.cpp:1546
NWidgetNewGRFDisplay::FillWidgetLookup
void FillWidgetLookup(WidgetLookup &widget_lookup) override
Fill the Window::widget_lookup with pointers to nested widgets in the tree.
Definition newgrf_gui.cpp:1717
NWidgetNewGRFDisplay::acs
std::unique_ptr< NWidgetBase > acs
Widget with the active grfs list and buttons.
Definition newgrf_gui.cpp:1544
NWidgetNewGRFDisplay::GetWidgetFromPos
NWidgetCore * GetWidgetFromPos(int x, int y) override
Retrieve a widget by its position.
Definition newgrf_gui.cpp:1725
NWidgetNewGRFDisplay::MAX_EXTRA_INFO_WIDTH
static const uint MAX_EXTRA_INFO_WIDTH
Maximal additional width given to the panel.
Definition newgrf_gui.cpp:1540
NWidgetNewGRFDisplay::AssignSizePosition
void AssignSizePosition(SizingType sizing, int x, int y, uint given_width, uint given_height, bool rtl) override
Assign size and position to the widget.
Definition newgrf_gui.cpp:1598
NWidgetNewGRFDisplay::Draw
void Draw(const Window *w) override
Draw the widgets of the tree.
Definition newgrf_gui.cpp:1735
NWidgetNewGRFDisplay::inf
std::unique_ptr< NWidgetBase > inf
Info panel.
Definition newgrf_gui.cpp:1545
NWidgetNewGRFDisplay::MIN_EXTRA_FOR_3_COLUMNS
static const uint MIN_EXTRA_FOR_3_COLUMNS
Minimal additional width needed before switching to 3 columns.
Definition newgrf_gui.cpp:1541
NWidgetNewGRFDisplay::SetupSmallestSize
void SetupSmallestSize(Window *w) override
Compute smallest size needed by the widget.
Definition newgrf_gui.cpp:1555
NWidgetNewGRFDisplay::avs
std::unique_ptr< NWidgetBase > avs
Widget with the available grfs list and buttons.
Definition newgrf_gui.cpp:1543
Scrollbar
Scrollbar data structure.
Definition widget_type.h:708
Scrollbar::IsVisible
bool IsVisible(size_type item) const
Checks whether given current item is visible in the list.
Definition widget_type.h:762
Scrollbar::SetCount
void SetCount(size_t num)
Sets the number of elements in the list.
Definition widget_type.h:792
Scrollbar::GetScrolledItemFromWidget
auto GetScrolledItemFromWidget(Tcontainer &container, int clickpos, const Window *const w, WidgetID widget, int padding=0, int line_height=-1) const
Return an iterator pointing to the element of a scrolled widget that a user clicked in.
Definition widget_type.h:891
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:2425
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:2499
Scrollbar::GetCount
size_type GetCount() const
Gets the number of elements in the list.
Definition widget_type.h:734
Scrollbar::UpdateListPositionOnKeyPress
EventState UpdateListPositionOnKeyPress(int &list_position, uint16_t keycode) const
Update the given list position as if it were on this scroll bar when the given keycode was pressed.
Definition widget.cpp:2446
Scrollbar::ScrollTowards
void ScrollTowards(size_type position)
Scroll towards the given position; if the item is visible nothing happens, otherwise it will be shown...
Definition widget_type.h:853
Scrollbar::GetVisibleRangeIterators
auto GetVisibleRangeIterators(Tcontainer &container) const
Get a pair of iterators for the range of visible elements in a container.
Definition widget_type.h:872
Scrollbar::GetPosition
size_type GetPosition() const
Gets the position of the first visible element in the list.
Definition widget_type.h:752
TimeoutTimer
A timeout timer will fire once after the interval.
Definition timer.h:116
TimeoutTimer::Reset
void Reset()
Reset the timer, so it will fire again after the timeout.
Definition timer.h:140
WidgetDimensions::framerect
RectPadding framerect
Standard padding inside many panels.
Definition window_gui.h:40
WidgetDimensions::frametext
RectPadding frametext
Padding inside frame with text.
Definition window_gui.h:41
WidgetDimensions::scaled
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition window_gui.h:30
WidgetDimensions::vsep_normal
int vsep_normal
Normal vertical spacing.
Definition window_gui.h:58
WidgetDimensions::vsep_wide
int vsep_wide
Wide vertical spacing.
Definition window_gui.h:60
WidgetDimensions::hsep_wide
int hsep_wide
Wide horizontal spacing.
Definition window_gui.h:62
WidgetDimensions::unscaled
static const WidgetDimensions unscaled
Unscaled widget dimensions.
Definition window_gui.h:93
WidgetDimensions::bevel
RectPadding bevel
Bevel thickness, affected by "scaled bevels" game option.
Definition window_gui.h:38
NETWORK_MAX_GRF_COUNT
static const uint NETWORK_MAX_GRF_COUNT
Maximum number of GRFs that can be sent.
Definition config.h:90
find_index
int find_index(Container const &container, typename Container::const_reference item)
Helper function to get the index of an item Consider using std::set, std::unordered_set or std::flat_...
Definition container_func.hpp:41
Slide
auto Slide(TIter first, TIter last, TIter position) -> std::pair< TIter, TIter >
Move elements between first and last to a new position, rotating elements in between as necessary.
Definition container_func.hpp:57
ShowDropDownListAt
void ShowDropDownListAt(Window *w, DropDownList &&list, int selected, WidgetID button, Rect wi_rect, Colours wi_colour, DropDownOptions options)
Show a drop down list.
Definition dropdown.cpp:402
ShowDropDownList
void ShowDropDownList(Window *w, DropDownList &&list, int selected, WidgetID button, uint width, DropDownOptions options)
Show a drop down list.
Definition dropdown.cpp:418
dropdown_func.h
Functions related to the drop down widget.
dropdown_type.h
Types related to the drop down widget.
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:56
error.h
Functions related to errors.
WL_ERROR
@ WL_ERROR
Errors (eg. saving/loading failed)
Definition error.h:26
WL_CRITICAL
@ WL_CRITICAL
Critical errors, the MessageBox is shown in all cases.
Definition error.h:27
WL_INFO
@ WL_INFO
Used for DoCommand-like (and some non-fatal AI GUI) errors/information.
Definition error.h:24
ShowErrorMessage
void ShowErrorMessage(EncodedString &&summary_msg, int x, int y, CommandCost &cc)
Display an error message in a window.
Definition error_gui.cpp:290
NEWGRF_DIR
@ NEWGRF_DIR
Subdirectory for all NewGRFs.
Definition fileio_type.h:97
fios.h
Declarations for savegames operations.
GetCharacterHeight
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition fontcache.cpp:87
_gamelog
Gamelog _gamelog
Gamelog instance.
Definition gamelog.cpp:31
gamelog.h
Functions to be called to log fundamental changes to the game.
GLAT_GRF
@ GLAT_GRF
GRF changed.
Definition gamelog.h:19
maxdim
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
Definition geometry_func.cpp:22
geometry_func.hpp
Geometry functions.
CentreBounds
int CentreBounds(int min, int max, int size)
Determine where to position a centred object.
Definition geometry_type.hpp:26
GetSpriteSize
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition gfx.cpp:965
GetStringBoundingBox
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition gfx.cpp:894
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:665
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:1031
GetStringMultiLineBoundingBox
Dimension GetStringMultiLineBoundingBox(StringID str, const Dimension &suggestion)
Calculate string bounding box for multi-line strings.
Definition gfx.cpp:748
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:782
GfxFillRect
void GfxFillRect(int left, int top, int right, int bottom, const std::variant< PixelColour, PaletteID > &colour, FillRectMode mode)
Applies a certain FillRectMode-operation to a rectangle [left, right] x [top, bottom] on the screen.
Definition gfx.cpp:115
GetScaledSpriteSize
Dimension GetScaledSpriteSize(SpriteID sprid)
Scale sprite size for GUI.
Definition widget.cpp:68
FS_NORMAL
@ FS_NORMAL
Index of the normal font in the font tables.
Definition gfx_type.h:249
SA_HOR_CENTER
@ SA_HOR_CENTER
Horizontally center the text.
Definition gfx_type.h:389
PaletteID
uint32_t PaletteID
The number of the palette.
Definition gfx_type.h:18
SetMatrixDataTip
constexpr NWidgetPart SetMatrixDataTip(uint32_t cols, uint32_t rows, StringID tip={})
Widget part function for setting the data and tooltip of WWT_MATRIX widgets.
Definition widget_type.h:1308
NWidgetFunction
constexpr NWidgetPart NWidgetFunction(NWidgetFunctionType *func_ptr)
Obtain a nested widget (sub)tree from an external source.
Definition widget_type.h:1445
SetFill
constexpr NWidgetPart SetFill(uint16_t fill_x, uint16_t fill_y)
Widget part function for setting filling.
Definition widget_type.h:1219
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:1375
SetScrollbar
constexpr NWidgetPart SetScrollbar(WidgetID index)
Attach a scrollbar to a widget.
Definition widget_type.h:1399
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:1332
SetStringTip
constexpr NWidgetPart SetStringTip(StringID string, StringID tip={})
Widget part function for setting the string and tooltip.
Definition widget_type.h:1240
SetMinimalSize
constexpr NWidgetPart SetMinimalSize(int16_t x, int16_t y)
Widget part function for setting the minimal size.
Definition widget_type.h:1156
SetResizeWidgetTypeTip
constexpr NWidgetPart SetResizeWidgetTypeTip(ResizeWidgetValues widget_type, StringID tip)
Widget part function for setting the resize widget type and tooltip.
Definition widget_type.h:1285
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:3374
SetToolTip
constexpr NWidgetPart SetToolTip(StringID tip)
Widget part function for setting tooltip and clearing the widget data.
Definition widget_type.h:1318
EndContainer
constexpr NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
Definition widget_type.h:1229
SetArrowWidgetTypeTip
constexpr NWidgetPart SetArrowWidgetTypeTip(ArrowWidgetValues widget_type, StringID tip={})
Widget part function for setting the arrow widget type and tooltip.
Definition widget_type.h:1274
NWidget
constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx=INVALID_WIDGET)
Widget part function for starting a new 'real' widget.
Definition widget_type.h:1424
SetResize
constexpr NWidgetPart SetResize(int16_t dx, int16_t dy)
Widget part function for setting the resize step.
Definition widget_type.h:1145
Window::SetDirty
void SetDirty() const
Mark entire window as dirty (in need of re-paint)
Definition window.cpp:966
IsInsideBS
constexpr bool IsInsideBS(const T x, const size_t base, const size_t size)
Checks if a value is between a window started at some base point.
Definition math_func.hpp:252
IsInsideMM
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
Definition math_func.hpp:267
ClampU
constexpr uint ClampU(const uint a, const uint min, const uint max)
Clamp an unsigned integer between an interval.
Definition math_func.hpp:150
ShowQuery
void ShowQuery(EncodedString &&caption, EncodedString &&message, Window *parent, QueryCallbackProc *callback, bool focus)
Show a confirmation window with standard 'yes' and 'no' buttons The window is aligned to the centre o...
Definition misc_gui.cpp:1202
ShowQueryString
void ShowQueryString(std::string_view str, StringID caption, uint maxsize, Window *parent, CharSetFilter afilter, QueryStringFlags flags)
Show a query popup window with a textbox in it.
Definition misc_gui.cpp:1062
misc_widget.h
Types related to the misc widgets.
WID_TF_CAPTION
@ WID_TF_CAPTION
The caption of the window.
Definition misc_widget.h:53
_network_available
bool _network_available
is network mode available?
Definition network.cpp:68
network.h
Basic functions/variables used all over the place.
network_content.h
Part of the network protocol handling content distribution.
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:1117
ContentVector
std::vector< std::unique_ptr< ContentInfo > > ContentVector
Vector with content info.
Definition network_content.h:20
newgrf.h
Base for the NewGRF implementation.
ReloadNewGRFData
void ReloadNewGRFData()
Reload all NewGRF files during a running game.
Definition afterload.cpp:3442
_grfconfig
GRFConfigList _grfconfig
First item in list of current GRF set up.
Definition newgrf_config.cpp:154
CopyGRFConfigList
void CopyGRFConfigList(GRFConfigList &dst, const GRFConfigList &src, bool init_only)
Copy a GRF Config list.
Definition newgrf_config.cpp:353
GRFBuildParamList
std::string GRFBuildParamList(const GRFConfig &c)
Build a string containing space separated parameter values, and terminate.
Definition newgrf_config.cpp:632
FindGRFConfig
const GRFConfig * FindGRFConfig(uint32_t grfid, FindGRFConfigMode mode, const MD5Hash *md5sum, uint32_t desired_version)
Find a NewGRF in the scanned list.
Definition newgrf_config.cpp:596
ResetGRFConfig
void ResetGRFConfig(bool defaults)
Reset the current GRF Config to either blank or newgame settings.
Definition newgrf_config.cpp:407
_all_grfs
GRFConfigList _all_grfs
First item in list of all scanned NewGRFs.
Definition newgrf_config.cpp:153
ClearGRFConfigList
void ClearGRFConfigList(GRFConfigList &config)
Clear a GRF Config list, freeing all nodes.
Definition newgrf_config.cpp:324
GCS_DISABLED
@ GCS_DISABLED
GRF file is disabled.
Definition newgrf_config.h:35
GCS_NOT_FOUND
@ GCS_NOT_FOUND
GRF file was not found in the local cache.
Definition newgrf_config.h:36
GCS_ACTIVATED
@ GCS_ACTIVATED
GRF file has been activated.
Definition newgrf_config.h:38
Compatible
@ Compatible
GRF file does not exactly match the requested GRF (different MD5SUM), but grfid matches)
Definition newgrf_config.h:24
Static
@ Static
GRF file is used statically (can be used in any MP game)
Definition newgrf_config.h:23
Invalid
@ Invalid
GRF is unusable with this version of OpenTTD.
Definition newgrf_config.h:28
PTYPE_UINT_ENUM
@ PTYPE_UINT_ENUM
The parameter allows a range of numbers, each of which can have a special name.
Definition newgrf_config.h:123
PTYPE_BOOL
@ PTYPE_BOOL
The parameter is either 0 or 1.
Definition newgrf_config.h:124
FGCM_NEWEST
@ FGCM_NEWEST
Find newest Grf.
Definition newgrf_config.h:210
FGCM_NEWEST_VALID
@ FGCM_NEWEST_VALID
Find newest Grf, ignoring Grfs with GRFConfigFlag::Invalid set.
Definition newgrf_config.h:211
FGCM_EXACT
@ FGCM_EXACT
Only find Grfs matching md5sum.
Definition newgrf_config.h:208
GRFP_GRF_UNSET
@ GRFP_GRF_UNSET
The NewGRF provided no information.
Definition newgrf_config.h:70
GRFP_USE_WINDOWS
@ GRFP_USE_WINDOWS
The palette state is set to use the Windows palette.
Definition newgrf_config.h:67
GRFP_BLT_32BPP
@ GRFP_BLT_32BPP
The NewGRF prefers a 32 bpp blitter.
Definition newgrf_config.h:77
GRFP_USE_MASK
@ GRFP_USE_MASK
Bitmask to get only the use palette use states.
Definition newgrf_config.h:68
GRFP_GRF_MASK
@ GRFP_GRF_MASK
Bitmask to get only the NewGRF supplied information.
Definition newgrf_config.h:74
ShowSavePresetWindow
static void ShowSavePresetWindow(std::string_view initial_text)
Open the window for saving a preset.
Definition newgrf_gui.cpp:2119
GrfIdMap
std::map< uint32_t, const GRFConfig * > GrfIdMap
Map of grfid to the grf config.
Definition newgrf_gui.cpp:576
_save_preset_desc
static WindowDesc _save_preset_desc(WDP_CENTER, "save_preset", 140, 110, WC_SAVE_PRESET, WC_GAME_OPTIONS, WindowDefaultFlag::Modal, _nested_save_preset_widgets)
Window description of the preset save window.
_scan_progress_desc
static WindowDesc _scan_progress_desc(WDP_CENTER, {}, 0, 0, WC_MODAL_PROGRESS, WC_NONE, {}, _nested_scan_progress_widgets)
Description of the widgets and other settings of the window.
NewGRFConfirmationCallback
static void NewGRFConfirmationCallback(Window *w, bool confirmed)
Callback function for the newgrf 'apply changes' confirmation window.
Definition newgrf_gui.cpp:1918
FillGrfidMap
static void FillGrfidMap(const GRFConfigList &lst, GrfIdMap &grfid_map)
Add all grf configs from c into the map.
Definition newgrf_gui.cpp:583
UpdateNewGRFScanStatus
void UpdateNewGRFScanStatus(uint num, std::string &&name)
Update the NewGRF scan status.
Definition newgrf_gui.cpp:2218
ShowNewGRFSettings
void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfigList &config)
Setup the NewGRF gui.
Definition newgrf_gui.cpp:1966
_nested_scan_progress_widgets
static constexpr std::initializer_list< NWidgetPart > _nested_scan_progress_widgets
Widgets for the progress window.
Definition newgrf_gui.cpp:2126
NewGRFDisplay
std::unique_ptr< NWidgetBase > NewGRFDisplay()
Construct nested container widget for managing the lists and the info panel of the NewGRF GUI.
Definition newgrf_gui.cpp:1879
_nested_save_preset_widgets
static constexpr std::initializer_list< NWidgetPart > _nested_save_preset_widgets
Widget parts of the save preset window.
Definition newgrf_gui.cpp:1973
_newgrf_parameters_desc
static WindowDesc _newgrf_parameters_desc(WDP_CENTER, "settings_newgrf_config", 500, 208, WC_GRF_PARAMETERS, WC_NONE, {}, _nested_newgrf_parameter_widgets)
Window definition for the change grf parameters window.
ShowNewGRFError
void ShowNewGRFError()
Show the first NewGRF error we can find.
Definition newgrf_gui.cpp:47
ShowMissingContentWindow
void ShowMissingContentWindow(const GRFConfigList &list)
Show the content list window with all missing grfs from the given list.
Definition newgrf_gui.cpp:1503
GetGRFStringFromGRFText
std::optional< std::string_view > GetGRFStringFromGRFText(const GRFTextList &text_list)
Get a C-string from a GRFText-list.
Definition newgrf_text.cpp:599
newgrf_text.h
Header of Action 04 "universal holder" structure and functions.
newgrf_widget.h
Types related to the newgrf widgets.
WID_NS_VIEW_PARAMETERS
@ WID_NS_VIEW_PARAMETERS
Open Parameters Window for selected NewGRF for viewing parameters.
Definition newgrf_widget.h:53
WID_NS_APPLY_CHANGES
@ WID_NS_APPLY_CHANGES
Apply changes to NewGRF config.
Definition newgrf_widget.h:55
WID_NS_OPEN_URL
@ WID_NS_OPEN_URL
Open URL of NewGRF.
Definition newgrf_widget.h:50
WID_NS_CONTENT_DOWNLOAD2
@ WID_NS_CONTENT_DOWNLOAD2
Open content download (active NewGRFs).
Definition newgrf_widget.h:59
WID_NS_RESCAN_FILES
@ WID_NS_RESCAN_FILES
Rescan files (available NewGRFs).
Definition newgrf_widget.h:56
WID_NS_CONTENT_DOWNLOAD
@ WID_NS_CONTENT_DOWNLOAD
Open content download (available NewGRFs).
Definition newgrf_widget.h:58
WID_NS_SHOW_EDIT
@ WID_NS_SHOW_EDIT
Select display of the buttons below the 'details'.
Definition newgrf_widget.h:61
WID_NS_MOVE_UP
@ WID_NS_MOVE_UP
Move NewGRF up in active list.
Definition newgrf_widget.h:40
WID_NS_SHOW_REMOVE
@ WID_NS_SHOW_REMOVE
Select active list buttons (0 = normal, 1 = simple layout).
Definition newgrf_widget.h:60
WID_NS_NEWGRF_INFO
@ WID_NS_NEWGRF_INFO
Panel for Info on selected NewGRF.
Definition newgrf_widget.h:49
WID_NS_NEWGRF_TEXTFILE
@ WID_NS_NEWGRF_TEXTFILE
Open NewGRF readme, changelog (+1) or license (+2).
Definition newgrf_widget.h:51
WID_NS_SET_PARAMETERS
@ WID_NS_SET_PARAMETERS
Open Parameters Window for selected NewGRF for editing parameters.
Definition newgrf_widget.h:52
WID_NS_ADD
@ WID_NS_ADD
Add NewGRF to active list.
Definition newgrf_widget.h:38
WID_NS_MOVE_DOWN
@ WID_NS_MOVE_DOWN
Move NewGRF down in active list.
Definition newgrf_widget.h:41
WID_NS_SCROLL2BAR
@ WID_NS_SCROLL2BAR
Scrollbar for available NewGRF list.
Definition newgrf_widget.h:47
WID_NS_UPGRADE
@ WID_NS_UPGRADE
Upgrade NewGRFs that have a newer version available.
Definition newgrf_widget.h:42
WID_NS_PRESET_SAVE
@ WID_NS_PRESET_SAVE
Save list of active NewGRFs as presets.
Definition newgrf_widget.h:36
WID_NS_FILTER
@ WID_NS_FILTER
Filter list of available NewGRFs.
Definition newgrf_widget.h:43
WID_NS_FILE_LIST
@ WID_NS_FILE_LIST
List window of active NewGRFs.
Definition newgrf_widget.h:44
WID_NS_SHOW_APPLY
@ WID_NS_SHOW_APPLY
Select display of the apply button.
Definition newgrf_widget.h:62
WID_NS_SCROLLBAR
@ WID_NS_SCROLLBAR
Scrollbar for active NewGRF list.
Definition newgrf_widget.h:45
WID_NS_PRESET_DELETE
@ WID_NS_PRESET_DELETE
Delete active preset.
Definition newgrf_widget.h:37
WID_NS_TOGGLE_PALETTE
@ WID_NS_TOGGLE_PALETTE
Toggle Palette of selected, active NewGRF.
Definition newgrf_widget.h:54
WID_NS_RESCAN_FILES2
@ WID_NS_RESCAN_FILES2
Rescan files (active NewGRFs).
Definition newgrf_widget.h:57
WID_NS_NEWGRF_INFO_TITLE
@ WID_NS_NEWGRF_INFO_TITLE
Title for Info on selected NewGRF.
Definition newgrf_widget.h:48
WID_NS_REMOVE
@ WID_NS_REMOVE
Remove NewGRF from active list.
Definition newgrf_widget.h:39
WID_NS_PRESET_LIST
@ WID_NS_PRESET_LIST
Active NewGRF preset.
Definition newgrf_widget.h:35
WID_NS_AVAIL_LIST
@ WID_NS_AVAIL_LIST
List window of available NewGRFs.
Definition newgrf_widget.h:46
WID_SP_PROGRESS_BAR
@ WID_SP_PROGRESS_BAR
Simple progress bar.
Definition newgrf_widget.h:75
WID_SP_PROGRESS_TEXT
@ WID_SP_PROGRESS_TEXT
Text explaining what is happening.
Definition newgrf_widget.h:76
WID_NP_NUMPAR_INC
@ WID_NP_NUMPAR_INC
Button to increase number of parameters.
Definition newgrf_widget.h:21
WID_NP_RESET
@ WID_NP_RESET
Reset button.
Definition newgrf_widget.h:26
WID_NP_NUMPAR_DEC
@ WID_NP_NUMPAR_DEC
Button to decrease number of parameters.
Definition newgrf_widget.h:20
WID_NP_SCROLLBAR
@ WID_NP_SCROLLBAR
Scrollbar to scroll through all settings.
Definition newgrf_widget.h:25
WID_NP_CAPTION
@ WID_NP_CAPTION
Caption of the window.
Definition newgrf_widget.h:18
WID_NP_SETTING_DROPDOWN
@ WID_NP_SETTING_DROPDOWN
Dynamically created dropdown for changing setting value.
Definition newgrf_widget.h:30
WID_NP_BACKGROUND
@ WID_NP_BACKGROUND
Panel to draw the settings on.
Definition newgrf_widget.h:24
WID_NP_NUMPAR
@ WID_NP_NUMPAR
Optional number of parameters.
Definition newgrf_widget.h:22
WID_NP_SHOW_NUMPAR
@ WID_NP_SHOW_NUMPAR
NWID_SELECTION to optionally display WID_NP_NUMPAR.
Definition newgrf_widget.h:19
WID_NP_SHOW_DESCRIPTION
@ WID_NP_SHOW_DESCRIPTION
NWID_SELECTION to optionally display parameter descriptions.
Definition newgrf_widget.h:27
WID_NP_DESCRIPTION
@ WID_NP_DESCRIPTION
Multi-line description of a parameter.
Definition newgrf_widget.h:28
WID_SVP_SAVE
@ WID_SVP_SAVE
Button to save the preset.
Definition newgrf_widget.h:70
WID_SVP_PRESET_LIST
@ WID_SVP_PRESET_LIST
List with available preset names.
Definition newgrf_widget.h:67
WID_SVP_SCROLLBAR
@ WID_SVP_SCROLLBAR
Scrollbar for the list available preset names.
Definition newgrf_widget.h:68
WID_SVP_EDITBOX
@ WID_SVP_EDITBOX
Edit box for changing the preset name.
Definition newgrf_widget.h:69
RequestNewGRFScan
bool RequestNewGRFScan(NewGRFScanCallback *callback)
Request a new NewGRF scan.
Definition openttd.cpp:1327
GetColourGradient
PixelColour GetColourGradient(Colours colour, ColourShade shade)
Get colour gradient palette index.
Definition palette.cpp:388
PC_DARK_BLUE
static constexpr PixelColour PC_DARK_BLUE
Dark blue palette colour.
Definition palette_func.h:116
PC_GREY
static constexpr PixelColour PC_GREY
Grey palette colour.
Definition palette_func.h:98
PC_DARK_GREY
static constexpr PixelColour PC_DARK_GREY
Dark grey palette colour.
Definition palette_func.h:97
PC_BLACK
static constexpr PixelColour PC_BLACK
Black palette colour.
Definition palette_func.h:96
querystring_gui.h
Base for the GUIs that have an edit box in them.
safeguards.h
A number of safeguards to prevent using unsafe methods.
SaveGRFPresetToConfig
void SaveGRFPresetToConfig(std::string_view config_name, GRFConfigList &config)
Save a NewGRF configuration with a preset name.
Definition settings.cpp:1581
GetGRFPresetList
StringList GetGRFPresetList()
Get the list of known NewGrf presets.
Definition settings.cpp:1544
DeleteGRFPresetFromConfig
void DeleteGRFPresetFromConfig(std::string_view config_name)
Delete a NewGRF configuration by preset name.
Definition settings.cpp:1595
LoadGRFPresetFromConfig
GRFConfigList LoadGRFPresetFromConfig(std::string_view config_name)
Load a NewGRF configuration by preset-name.
Definition settings.cpp:1564
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:60
settings_func.h
Functions related to setting/changing the settings.
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:1866
DrawBoolButton
void DrawBoolButton(int x, int y, Colours button_colour, Colours background, bool state, bool clickable)
Draw a toggle button.
Definition settings_gui.cpp:1947
DrawDropDownButton
void DrawDropDownButton(int x, int y, Colours button_colour, bool state, bool clickable)
Draw a dropdown button.
Definition settings_gui.cpp:1924
settings_gui.h
Functions for setting GUIs.
SETTING_BUTTON_WIDTH
#define SETTING_BUTTON_WIDTH
Width of setting buttons.
Definition settings_gui.h:17
SETTING_BUTTON_HEIGHT
#define SETTING_BUTTON_HEIGHT
Height of setting buttons.
Definition settings_gui.h:19
settings_type.h
Types related to global configuration settings.
sortlist_type.h
Base types for having sorted lists in GUIs.
sprites.h
This file contains all sprite-related enums and defines.
SPR_CURSOR_MOUSE
static const CursorID SPR_CURSOR_MOUSE
Cursor sprite numbers.
Definition sprites.h:1404
stdafx.h
Definition of base types and functions in a cross-platform compatible way.
FormatArrayAsHex
std::string FormatArrayAsHex(std::span< const uint8_t > data)
Format a byte array into a continuous hex string.
Definition string.cpp:77
StrNaturalCompare
int StrNaturalCompare(std::string_view s1, std::string_view s2, bool ignore_garbage_at_front)
Compares two strings using case insensitive natural sort.
Definition string.cpp:427
StrMakeValid
static void StrMakeValid(Builder &builder, StringConsumer &consumer, StringValidationSettings settings)
Copies the valid (UTF-8) characters from consumer to the builder.
Definition string.cpp:119
string_consumer.hpp
Parse strings.
CS_NUMERAL
@ CS_NUMERAL
Only numeric ones.
Definition string_type.h:26
StringList
std::vector< std::string > StringList
Type for a list of strings.
Definition string_type.h:60
stringfilter_type.h
Searching and filtering using a stringterm.
GetParamMaxValue
uint64_t GetParamMaxValue(uint64_t max_value, uint min_count, FontSize size)
Get some number that is suitable for string size computations.
Definition strings.cpp:236
GetEncodedStringWithArgs
EncodedString GetEncodedStringWithArgs(StringID str, std::span< const StringParameter > params)
Encode a string with its parameters into an encoded string.
Definition strings.cpp:102
GetStringWithArgs
void GetStringWithArgs(StringBuilder &builder, StringID string, StringParameters &args, uint case_index, bool game_script)
Get a parsed string with most special stringcodes replaced by the string parameters.
Definition strings.cpp:336
GetEncodedString
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
Definition strings.cpp:90
GetString
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
Definition strings.cpp:424
_current_text_dir
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition strings.cpp:56
GetParamMaxDigits
uint64_t GetParamMaxDigits(uint count, FontSize size)
Get some number that is suitable for string size computations.
Definition strings.cpp:218
strings_func.h
Functions related to OTTD's strings.
StringID
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Definition strings_type.h:19
TD_RTL
@ TD_RTL
Text is written right-to-left by default.
Definition strings_type.h:27
ClientSettings::gui
GUISettings gui
settings related to the GUI
Definition settings_type.h:650
ContentInfo::State::DoesNotExist
@ DoesNotExist
The content does not exist in the content system.
Coord2D< int >
Coord2D::y
T y
Y coordinate.
Definition geometry_type.hpp:35
Dimension
Dimensions (a width and height) of a rectangle in 2D.
Definition geometry_type.hpp:56
Filtering
Data structure describing what to show in the list (filter criteria).
Definition sortlist_type.h:31
GRFConfig
Information about GRF, used in the game and (part of it) in savegames.
Definition newgrf_config.h:158
GRFConfig::original_md5sum
MD5Hash original_md5sum
MD5 checksum of original file if only a 'compatible' file was loaded.
Definition newgrf_config.h:169
GRFConfig::SetParameterDefaults
void SetParameterDefaults()
Set the default value for all parameters as specified by action14.
Definition newgrf_config.cpp:114
GRFConfig::palette
uint8_t palette
GRFPalette, bitset.
Definition newgrf_config.h:182
GRFConfig::param_info
std::vector< std::optional< GRFParameterInfo > > param_info
NOSAVE: extra information about the parameters.
Definition newgrf_config.h:184
GRFConfig::errors
std::vector< GRFError > errors
NOSAVE: Error/Warning during GRF loading (Action 0x0B)
Definition newgrf_config.h:174
GRFConfig::version
uint32_t version
NOSAVE: Version a NewGRF can set so only the newest NewGRF is shown.
Definition newgrf_config.h:176
GRFConfig::param
std::vector< uint32_t > param
GRF parameters.
Definition newgrf_config.h:185
GRFConfig::GetURL
std::optional< std::string > GetURL() const
Get the grf url.
Definition newgrf_config.cpp:106
GRFConfig::status
GRFStatus status
NOSAVE: GRFStatus, enum.
Definition newgrf_config.h:179
GRFConfig::SetValue
void SetValue(const GRFParameterInfo &info, uint32_t value)
Set the value of the given user-changeable parameter.
Definition newgrf_config.cpp:180
GRFConfig::GetTextfile
std::optional< std::string > GetTextfile(TextfileType type) const
Search a textfile file next to this NewGRF.
Definition newgrf_config.cpp:647
GRFConfig::flags
GRFConfigFlags flags
NOSAVE: GCF_Flags, bitset.
Definition newgrf_config.h:178
GRFConfig::num_valid_params
uint8_t num_valid_params
NOSAVE: Number of valid parameters (action 0x14)
Definition newgrf_config.h:181
GRFConfig::filename
std::string filename
Filename - either with or without full path.
Definition newgrf_config.h:170
GRFConfig::ident
GRFIdentifier ident
grfid and md5sum to uniquely identify newgrfs
Definition newgrf_config.h:168
GRFConfig::min_loadable_version
uint32_t min_loadable_version
NOSAVE: Minimum compatible version a NewGRF can define.
Definition newgrf_config.h:177
GRFConfig::GetName
std::string GetName() const
Get the name of this grf.
Definition newgrf_config.cpp:85
GRFConfig::GetDescription
std::optional< std::string > GetDescription() const
Get the grf info.
Definition newgrf_config.cpp:95
GRFConfig::GetValue
uint32_t GetValue(const GRFParameterInfo &info) const
Get the value of the given user-changeable parameter.
Definition newgrf_config.cpp:164
GRFError
Information about why GRF had problems during initialisation.
Definition newgrf_config.h:109
GRFError::severity
StringID severity
Info / Warning / Error / Fatal.
Definition newgrf_config.h:116
GRFError::param_value
std::array< uint32_t, 2 > param_value
Values of GRF parameters to show for message and custom_message.
Definition newgrf_config.h:118
GRFError::message
StringID message
Default message.
Definition newgrf_config.h:115
GRFError::custom_message
std::string custom_message
Custom message (if present)
Definition newgrf_config.h:113
GRFError::data
std::string data
Additional data for message and custom_message.
Definition newgrf_config.h:114
GRFIdentifier::HasGrfIdentifier
bool HasGrfIdentifier(uint32_t grfid, const MD5Hash *md5sum) const
Does the identification match the provided values?
Definition newgrf_config.h:100
GRFIdentifier::grfid
uint32_t grfid
GRF ID (defined by Action 0x08)
Definition newgrf_config.h:84
GRFIdentifier::md5sum
MD5Hash md5sum
MD5 checksum of file to distinguish files with the same GRF ID (eg. newer version of GRF)
Definition newgrf_config.h:85
GRFParameterInfo
Information about one grf parameter.
Definition newgrf_config.h:129
GRFParameterInfo::complete_labels
bool complete_labels
True if all values have a label.
Definition newgrf_config.h:149
GRFParameterInfo::param_nr
uint8_t param_nr
GRF parameter to store content in.
Definition newgrf_config.h:145
GRFParameterInfo::min_value
uint32_t min_value
The minimal value this parameter can have.
Definition newgrf_config.h:139
GRFParameterInfo::max_value
uint32_t max_value
The maximal value of this parameter.
Definition newgrf_config.h:140
GRFParameterInfo::type
GRFParameterType type
The type of this parameter.
Definition newgrf_config.h:143
GRFParameterInfo::value_names
std::vector< ValueName > value_names
Names for each value.
Definition newgrf_config.h:152
GRFParameterInfo::name
GRFTextList name
The name of this parameter.
Definition newgrf_config.h:136
GRFParameterInfo::desc
GRFTextList desc
The description of this parameter.
Definition newgrf_config.h:137
GUISettings::last_newgrf_count
uint32_t last_newgrf_count
the numbers of NewGRFs we found during the last scan
Definition settings_type.h:227
GUISettings::newgrf_show_old_versions
bool newgrf_show_old_versions
whether to show old versions in the NewGRF list
Definition settings_type.h:255
GUISettings::scenario_developer
bool scenario_developer
activate scenario developer: allow modifying NewGRFs in an existing game
Definition settings_type.h:253
GUISettings::newgrf_developer_tools
bool newgrf_developer_tools
activate NewGRF developer tools and allow modifying NewGRFs in an existing game
Definition settings_type.h:251
Listing
Data structure describing how to show the list (what sort direction and criteria).
Definition sortlist_type.h:26
NewGRFParametersWindow
Window for setting the parameters of a NewGRF.
Definition newgrf_gui.cpp:145
NewGRFParametersWindow::clicked_dropdown
bool clicked_dropdown
Whether the dropdown is open.
Definition newgrf_gui.cpp:150
NewGRFParametersWindow::GetWidgetString
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
Definition newgrf_gui.cpp:250
NewGRFParametersWindow::OnQueryTextFinished
void OnQueryTextFinished(std::optional< std::string > str) override
The query window opened from this window has closed.
Definition newgrf_gui.cpp:438
NewGRFParametersWindow::OnDropdownClose
void OnDropdownClose(Point, WidgetID widget, int, int, bool) override
A dropdown window associated to this window has been closed.
Definition newgrf_gui.cpp:457
NewGRFParametersWindow::OnPaint
void OnPaint() override
The window must be repainted.
Definition newgrf_gui.cpp:322
NewGRFParametersWindow::OnInvalidateData
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition newgrf_gui.cpp:479
NewGRFParametersWindow::editable
bool editable
Allow editing parameters.
Definition newgrf_gui.cpp:156
NewGRFParametersWindow::HasParameterInfo
bool HasParameterInfo(uint nr) const
Test if GRF Parameter Info exists for a given parameter index.
Definition newgrf_gui.cpp:192
NewGRFParametersWindow::dummy_parameter_info
static GRFParameterInfo dummy_parameter_info
Dummy info in case a newgrf didn't provide info about some parameter.
Definition newgrf_gui.cpp:146
NewGRFParametersWindow::OnClick
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
Definition newgrf_gui.cpp:331
NewGRFParametersWindow::OnDropdownSelect
void OnDropdownSelect(WidgetID widget, int index, int) override
A dropdown option associated to this window has been selected.
Definition newgrf_gui.cpp:448
NewGRFParametersWindow::unclick_timeout
TimeoutTimer< TimerWindow > unclick_timeout
When reset, unclick the button after a small timeout.
Definition newgrf_gui.cpp:495
NewGRFParametersWindow::action14present
bool action14present
True if action14 information is present.
Definition newgrf_gui.cpp:155
NewGRFParametersWindow::UpdateWidgetSize
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
Definition newgrf_gui.cpp:208
NewGRFParametersWindow::line_height
int line_height
Height of a row in the matrix widget.
Definition newgrf_gui.cpp:153
NewGRFParametersWindow::clicked_increase
bool clicked_increase
True if the increase button was clicked, false for the decrease button.
Definition newgrf_gui.cpp:149
NewGRFParametersWindow::clicked_row
int32_t clicked_row
The selected parameter, or INT32_MAX when none is selected.
Definition newgrf_gui.cpp:152
NewGRFParametersWindow::closing_dropdown
bool closing_dropdown
True, if the dropdown list is currently closing.
Definition newgrf_gui.cpp:151
NewGRFParametersWindow::grf_config
GRFConfig & grf_config
Set the parameters of this GRFConfig.
Definition newgrf_gui.cpp:147
NewGRFParametersWindow::clicked_button
int32_t clicked_button
The row in which a button was clicked or INT32_MAX when none is selected.
Definition newgrf_gui.cpp:148
NewGRFParametersWindow::GetDummyParameterInfo
static GRFParameterInfo & GetDummyParameterInfo(uint nr)
Get a dummy parameter-info object with default information.
Definition newgrf_gui.cpp:181
NewGRFParametersWindow::GetParameterInfo
GRFParameterInfo & GetParameterInfo(uint nr) const
Get GRF Parameter Info exists for a given parameter index.
Definition newgrf_gui.cpp:203
NewGRFParametersWindow::DrawWidget
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
Definition newgrf_gui.cpp:282
NewGRFParametersWindow::OnResize
void OnResize() override
Called after the window got resized.
Definition newgrf_gui.cpp:469
NewGRFScanCallback
Callback for NewGRF scanning.
Definition newgrf_config.h:222
NewGRFTextfileWindow
Window for displaying the textfile of a NewGRF.
Definition newgrf_gui.cpp:549
NewGRFTextfileWindow::GetWidgetString
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
Definition newgrf_gui.cpp:560
NewGRFTextfileWindow::grf_config
const GRFConfig * grf_config
View the textfile of this GRFConfig.
Definition newgrf_gui.cpp:550
NewGRFWindow
Window for showing NewGRF files.
Definition newgrf_gui.cpp:596
NewGRFWindow::UpdateWidgetSize
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
Definition newgrf_gui.cpp:730
NewGRFWindow::editable
bool editable
Is the window editable?
Definition newgrf_gui.cpp:618
NewGRFWindow::OnEditboxChanged
void OnEditboxChanged(WidgetID widget) override
The text in an editbox has been edited.
Definition newgrf_gui.cpp:1312
NewGRFWindow::CanUpgradeCurrent
bool CanUpgradeCurrent()
Test whether the currently active set of NewGRFs can be upgraded with the available NewGRFs.
Definition newgrf_gui.cpp:690
NewGRFWindow::active_sel
GRFConfig * active_sel
Selected active grf item.
Definition newgrf_gui.cpp:615
NewGRFWindow::OnClick
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
Definition newgrf_gui.cpp:926
NewGRFWindow::show_params
bool show_params
Are the grf-parameters shown in the info-panel?
Definition newgrf_gui.cpp:619
NewGRFWindow::UpgradeCurrent
void UpgradeCurrent()
Upgrade the currently active set of NewGRFs.
Definition newgrf_gui.cpp:703
NewGRFWindow::OnResize
void OnResize() override
Called after the window got resized.
Definition newgrf_gui.cpp:781
NewGRFWindow::GetWidgetString
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
Definition newgrf_gui.cpp:787
NewGRFWindow::AddGRFToActive
bool AddGRFToActive(int ins_pos=-1)
Insert a GRF into the active list.
Definition newgrf_gui.cpp:1460
NewGRFWindow::actives
GRFConfigList actives
Temporary active grf list to which changes are made.
Definition newgrf_gui.cpp:614
NewGRFWindow::avail_pos
int avail_pos
Index of avail_sel if existing, else -1.
Definition newgrf_gui.cpp:608
NewGRFWindow::active_over
int active_over
Active GRF item over which another one is dragged, -1 if none.
Definition newgrf_gui.cpp:622
NewGRFWindow::DrawWidget
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
Definition newgrf_gui.cpp:835
NewGRFWindow::OnMouseDrag
void OnMouseDrag(Point pt, WidgetID widget) override
An 'object' is being dragged at the provided position, highlight the target if possible.
Definition newgrf_gui.cpp:1364
NewGRFWindow::modified
bool modified
The list of active NewGRFs has been modified since the last time they got saved.
Definition newgrf_gui.cpp:623
NewGRFWindow::execute
bool execute
On pressing 'apply changes' are grf changes applied immediately, or only list is updated.
Definition newgrf_gui.cpp:620
NewGRFWindow::orig_list
GRFConfigList & orig_list
List active grfs in the game. Used as initial value, may be updated by the window.
Definition newgrf_gui.cpp:617
NewGRFWindow::OnKeyPress
EventState OnKeyPress(char32_t key, uint16_t keycode) override
A key has been pressed.
Definition newgrf_gui.cpp:1294
NewGRFWindow::preset
int preset
Selected preset or -1 if none selected.
Definition newgrf_gui.cpp:621
NewGRFWindow::GetPalette
PaletteID GetPalette(const GRFConfig &c) const
Pick the palette for the sprite of the grf to display.
Definition newgrf_gui.cpp:805
NewGRFWindow::grf_presets
StringList grf_presets
List of known NewGRF presets.
Definition newgrf_gui.cpp:612
NewGRFWindow::avail_sel
const GRFConfig * avail_sel
Currently selected available grf. nullptr is none is selected.
Definition newgrf_gui.cpp:607
NewGRFWindow::UpdateScrollBars
void UpdateScrollBars()
Updates the scroll bars for the active and inactive NewGRF lists.
Definition newgrf_gui.cpp:1183
NewGRFWindow::filter_editbox
QueryString filter_editbox
Filter editbox;.
Definition newgrf_gui.cpp:610
NewGRFWindow::TagNameFilter
static bool TagNameFilter(const GRFConfig *const *a, StringFilter &filter)
Filter grfs by tags/name.
Definition newgrf_gui.cpp:1403
NewGRFWindow::OnDropdownSelect
void OnDropdownSelect(WidgetID widget, int index, int) override
A dropdown option associated to this window has been selected.
Definition newgrf_gui.cpp:1142
NewGRFWindow::OnDragDrop
void OnDragDrop(Point pt, WidgetID widget) override
A dragged 'object' has been released.
Definition newgrf_gui.cpp:1324
NewGRFWindow::last_filtering
static Filtering last_filtering
Default filtering of GUIGRFConfigList.
Definition newgrf_gui.cpp:1522
NewGRFWindow::OnInvalidateData
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition newgrf_gui.cpp:1196
NewGRFWindow::sorter_funcs
static const std::initializer_list< GUIGRFConfigList::SortFunction *const > sorter_funcs
Sort functions of the GUIGRFConfigList.
Definition newgrf_gui.cpp:1524
NewGRFWindow::OnQueryTextFinished
void OnQueryTextFinished(std::optional< std::string > str) override
The query window opened from this window has closed.
Definition newgrf_gui.cpp:1162
NewGRFWindow::filter_funcs
static const std::initializer_list< GUIGRFConfigList::FilterFunction *const > filter_funcs
Filter functions of the GUIGRFConfigList.
Definition newgrf_gui.cpp:1528
NewGRFWindow::OnNewGRFsScanned
void OnNewGRFsScanned() override
Called whenever the NewGRF scan completed.
Definition newgrf_gui.cpp:1133
NewGRFWindow::avails
GUIGRFConfigList avails
Available (non-active) grfs.
Definition newgrf_gui.cpp:606
NewGRFWindow::string_filter
StringFilter string_filter
Filter for available grf.
Definition newgrf_gui.cpp:609
NewGRFWindow::last_sorting
static Listing last_sorting
Default sorting of GUIGRFConfigList.
Definition newgrf_gui.cpp:1521
NewGRFWindow::NameSorter
static bool NameSorter(const GRFConfig *const &a, const GRFConfig *const &b)
Sort grfs by name.
Definition newgrf_gui.cpp:1389
NewGRFWindow::Close
void Close(int data=0) override
Hide the window and all its child windows, and mark them for a later deletion.
Definition newgrf_gui.cpp:663
QueryString
Data stored about a string that can be modified in the GUI.
Definition querystring_gui.h:20
QueryString::ok_button
int ok_button
Widget button of parent window to simulate when pressing OK in OSK.
Definition querystring_gui.h:27
QueryString::cancel_button
int cancel_button
Widget button of parent window to simulate when pressing CANCEL in OSK.
Definition querystring_gui.h:28
QueryString::ACTION_CLEAR
static const int ACTION_CLEAR
Clear editbox.
Definition querystring_gui.h:24
RectPadding::Horizontal
constexpr uint Horizontal() const
Get total horizontal padding of RectPadding.
Definition geometry_type.hpp:89
RectPadding::Vertical
constexpr uint Vertical() const
Get total vertical padding of RectPadding.
Definition geometry_type.hpp:95
Rect
Specification of a rectangle with absolute coordinates of all edges.
Definition geometry_type.hpp:101
Rect::Width
int Width() const
Get width of Rect.
Definition geometry_type.hpp:111
Rect::Shrink
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
Definition geometry_type.hpp:124
Rect::Indent
Rect Indent(int indent, bool end) const
Copy Rect and indent it from its position.
Definition geometry_type.hpp:224
SavePresetWindow
Class for the save preset window.
Definition newgrf_gui.cpp:2005
SavePresetWindow::presetname_editbox
QueryString presetname_editbox
Edit box of the save preset.
Definition newgrf_gui.cpp:2006
SavePresetWindow::UpdateWidgetSize
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
Definition newgrf_gui.cpp:2043
SavePresetWindow::DrawWidget
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
Definition newgrf_gui.cpp:2059
SavePresetWindow::OnResize
void OnResize() override
Called after the window got resized.
Definition newgrf_gui.cpp:2109
SavePresetWindow::selected
int selected
Selected entry in the preset list, or -1 if none selected.
Definition newgrf_gui.cpp:2009
SavePresetWindow::vscroll
Scrollbar * vscroll
Pointer to the scrollbar widget.
Definition newgrf_gui.cpp:2008
SavePresetWindow::presets
StringList presets
Available presets.
Definition newgrf_gui.cpp:2007
SavePresetWindow::SavePresetWindow
SavePresetWindow(std::string_view initial_text)
Constructor of the save preset window.
Definition newgrf_gui.cpp:2015
SavePresetWindow::OnClick
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
Definition newgrf_gui.cpp:2083
ScanProgressWindow
Window for showing the progress of NewGRF scanning.
Definition newgrf_gui.cpp:2146
ScanProgressWindow::last_name
std::string last_name
The name of the last 'seen' NewGRF.
Definition newgrf_gui.cpp:2147
ScanProgressWindow::scanned
int scanned
The number of NewGRFs that we have seen.
Definition newgrf_gui.cpp:2148
ScanProgressWindow::UpdateNewGRFScanStatus
void UpdateNewGRFScanStatus(uint num, std::string &&name)
Update the NewGRF scan status.
Definition newgrf_gui.cpp:2203
ScanProgressWindow::ScanProgressWindow
ScanProgressWindow()
Create the window.
Definition newgrf_gui.cpp:2151
ScanProgressWindow::DrawWidget
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
Definition newgrf_gui.cpp:2177
ScanProgressWindow::UpdateWidgetSize
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
Definition newgrf_gui.cpp:2156
StringFilter
String filter and state.
Definition stringfilter_type.h:30
StringFilter::IsEmpty
bool IsEmpty() const
Check whether any filter words were entered.
Definition stringfilter_type.h:57
StringFilter::SetFilterTerm
void SetFilterTerm(std::string_view str)
Set the term to filter on.
Definition stringfilter.cpp:29
StringFilter::ResetState
void ResetState()
Reset the matching state to process a new item.
Definition stringfilter.cpp:80
StringFilter::GetState
bool GetState() const
Get the matching state of the current item.
Definition stringfilter_type.h:67
StringParameter
The data required to format and validate a single parameter of a string.
Definition strings_type.h:78
Textbuf::GetText
std::string_view GetText() const
Get the current text.
Definition textbuf.cpp:284
Textbuf::Assign
void Assign(std::string_view text)
Copy a string into the textbuffer.
Definition textbuf.cpp:420
TextfileWindow
Window for displaying a textfile.
Definition textfile_gui.h:22
TextfileWindow::file_type
TextfileType file_type
Type of textfile to view.
Definition textfile_gui.h:23
TextfileWindow::LoadTextfile
virtual void LoadTextfile(const std::string &textfile, Subdirectory dir)
Loads the textfile text from file and setup lines.
Definition textfile_gui.cpp:851
WindowDesc
High level window description.
Definition window_gui.h:168
Window
Data structure for an opened window.
Definition window_gui.h:274
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:1102
Window::FinishInitNested
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition window.cpp:1807
Window::querystrings
std::map< WidgetID, QueryString * > querystrings
QueryString associated to WWT_EDITBOX widgets.
Definition window_gui.h:321
Window::DrawWidgets
void DrawWidgets() const
Paint all widgets of a window.
Definition widget.cpp:766
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:3234
Window::parent
Window * parent
Parent window.
Definition window_gui.h:329
Window::SetWidgetDirty
void SetWidgetDirty(WidgetID widget_index) const
Invalidate a widget, i.e.
Definition window.cpp:556
Window::GetWidgetString
virtual std::string GetWidgetString(WidgetID widget, StringID stringid) const
Get the raw string for a widget.
Definition window.cpp:504
Window::CloseChildWindows
void CloseChildWindows(WindowClass wc=WC_INVALID) const
Close all children a window might have in a head-recursive manner.
Definition window.cpp:1075
Window::resize
ResizeInfo resize
Resize information.
Definition window_gui.h:315
Window::DisableWidget
void DisableWidget(WidgetID widget_index)
Sets a widget to disabled.
Definition window_gui.h:392
Window::SetWidgetsDisabledState
void SetWidgetsDisabledState(bool disab_stat, Args... widgets)
Sets the enabled/disabled status of a list of widgets.
Definition window_gui.h:516
Window::CreateNestedTree
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
Definition window.cpp:1797
Window::CloseChildWindowById
void CloseChildWindowById(WindowClass wc, WindowNumber number) const
Close all children a window might have in a head-recursive manner.
Definition window.cpp:1090
Window::OnQueryTextFinished
virtual void OnQueryTextFinished(std::optional< std::string > str)
The query window opened from this window has closed.
Definition window_gui.h:786
Window::SetFocusedWidget
bool SetFocusedWidget(WidgetID widget_index)
Set focus within this window to the given widget.
Definition window.cpp:485
Window::top
int top
y position of top edge of the window
Definition window_gui.h:311
Window::InitNested
void InitNested(WindowNumber number=0)
Perform complete initialization of the Window with nested widgets, to allow use.
Definition window.cpp:1820
Window::GetScrollbar
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
Definition window.cpp:313
Window::SetWidgetDisabledState
void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition window_gui.h:382
Window::width
int width
width of the window (number of pixels to the right in x direction)
Definition window_gui.h:312
CONTENT_TYPE_NEWGRF
@ CONTENT_TYPE_NEWGRF
The content consists of a NewGRF.
Definition tcp_content_type.h:24
textfile_gui.h
GUI functions related to textfiles.
TextfileType
TextfileType
Additional text files accompanying Tar archives.
Definition textfile_type.h:14
TFT_LICENSE
@ TFT_LICENSE
Content license.
Definition textfile_type.h:19
TFT_README
@ TFT_README
Content readme.
Definition textfile_type.h:17
TFT_CHANGELOG
@ TFT_CHANGELOG
Content changelog.
Definition textfile_type.h:18
tilehighlight_func.h
Functions related to tile highlights.
ResetObjectToPlace
void ResetObjectToPlace()
Reset the cursor and mouse mode handling back to default (normal cursor, only clicking in windows).
Definition viewport.cpp:3573
SetObjectToPlaceWnd
void SetObjectToPlaceWnd(CursorID icon, PaletteID pal, HighLightStyle mode, Window *w)
Change the cursor and mouse click/drag handling to a mode for performing special operations like tile...
Definition viewport.cpp:3510
HT_DRAG
@ HT_DRAG
dragging items in the depot windows
Definition tilehighlight_type.h:24
timer.h
Definition of Interval and OneShot timers.
timer_window.h
Definition of the Window system.
DrawFrameRect
void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, FrameFlags flags)
Draw frame rectangle.
Definition widget.cpp:289
ScaleGUITrad
static RectPadding ScaleGUITrad(const RectPadding &r)
Scale a RectPadding to GUI zoom level.
Definition widget.cpp:49
WWT_PUSHTXTBTN
@ WWT_PUSHTXTBTN
Normal push-button (no toggle button) with text caption.
Definition widget_type.h:104
WWT_INSET
@ WWT_INSET
Pressed (inset) panel, most commonly used as combo box text area.
Definition widget_type.h:40
NWID_CUSTOM
@ NWID_CUSTOM
General Custom widget.
Definition widget_type.h:77
WWT_PUSHARROWBTN
@ WWT_PUSHARROWBTN
Normal push-button (no toggle button) with arrow caption.
Definition widget_type.h:106
WWT_LABEL
@ WWT_LABEL
Centered label.
Definition widget_type.h:48
NWID_SPACER
@ NWID_SPACER
Invisible widget that takes some space.
Definition widget_type.h:70
WWT_EDITBOX
@ WWT_EDITBOX
a textbox for typing
Definition widget_type.h:62
NWID_HORIZONTAL
@ NWID_HORIZONTAL
Horizontal container.
Definition widget_type.h:66
WWT_PANEL
@ WWT_PANEL
Simple depressed panel.
Definition widget_type.h:39
WWT_MATRIX
@ WWT_MATRIX
Grid of rows and columns.
Definition widget_type.h:50
WWT_CAPTION
@ WWT_CAPTION
Window caption (window title between closebox and stickybox)
Definition widget_type.h:52
NWID_VSCROLLBAR
@ NWID_VSCROLLBAR
Vertical scrollbar.
Definition widget_type.h:76
NWID_VERTICAL
@ NWID_VERTICAL
Vertical container.
Definition widget_type.h:68
WWT_CLOSEBOX
@ WWT_CLOSEBOX
Close box (at top-left of a window)
Definition widget_type.h:60
WWT_FRAME
@ WWT_FRAME
Frame.
Definition widget_type.h:51
WWT_EMPTY
@ WWT_EMPTY
Empty widget, place holder to reserve space in widget tree.
Definition widget_type.h:37
WWT_RESIZEBOX
@ WWT_RESIZEBOX
Resize box (normally at bottom-right of a window)
Definition widget_type.h:59
WWT_DEFSIZEBOX
@ WWT_DEFSIZEBOX
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX)
Definition widget_type.h:56
WWT_DROPDOWN
@ WWT_DROPDOWN
Drop down list.
Definition widget_type.h:61
WWT_TEXT
@ WWT_TEXT
Pure simple text.
Definition widget_type.h:49
NWID_SELECTION
@ NWID_SELECTION
Stacked widgets, only one visible at a time (eg in a panel with tabs).
Definition widget_type.h:71
ComputeMaxSize
uint ComputeMaxSize(uint base, uint max_space, uint step)
Return the biggest possible size of a nested widget.
Definition widget_type.h:956
SZSP_HORIZONTAL
@ SZSP_HORIZONTAL
Display plane with zero size vertically, and filling and resizing horizontally.
Definition widget_type.h:505
SZSP_VERTICAL
@ SZSP_VERTICAL
Display plane with zero size horizontally, and filling and resizing vertically.
Definition widget_type.h:504
EqualSize
@ EqualSize
Containers should keep all their (resizing) children equally large.
Definition widget_type.h:541
SizingType
SizingType
Different forms of sizing nested widgets, using NWidgetBase::AssignSizePosition()
Definition widget_type.h:112
AWV_DECREASE
@ AWV_DECREASE
Arrow to the left or in case of RTL to the right.
Definition widget_type.h:20
AWV_INCREASE
@ AWV_INCREASE
Arrow to the right or in case of RTL to the left.
Definition widget_type.h:21
WidgetLookup
std::map< WidgetID, class NWidgetBase * > WidgetLookup
Lookup between widget IDs and NWidget objects.
Definition widget_type.h:128
RWV_HIDE_BEVEL
@ RWV_HIDE_BEVEL
Bevel of resize box is hidden.
Definition widget_type.h:29
FindWindowByClass
Window * FindWindowByClass(WindowClass cls)
Find any window by its class.
Definition window.cpp:1166
ReInitAllWindows
void ReInitAllWindows(bool zoom_changed)
Re-initialize all windows.
Definition window.cpp:3410
CloseWindowByClass
void CloseWindowByClass(WindowClass cls, int data)
Close all windows of a given class.
Definition window.cpp:1205
FindWindowById
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
Definition window.cpp:1151
SetWindowDirty
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition window.cpp:3176
window_func.h
Window functions not directly related to making/drawing windows.
WindowDefaultFlag::Modal
@ Modal
The window is a modal child of some other window, meaning the parent is 'inactive'.
FrameFlag::BorderOnly
@ BorderOnly
Draw border only, no background.
FrameFlag::Lowered
@ Lowered
If set the frame is lowered and the background colour brighter (ie. buttons when pressed)
WDP_CENTER
@ WDP_CENTER
Center the window.
Definition window_gui.h:145
WidgetID
int WidgetID
Widget ID.
Definition window_type.h:20
WN_GAME_OPTIONS_NEWGRF_STATE
@ WN_GAME_OPTIONS_NEWGRF_STATE
NewGRF settings.
Definition window_type.h:30
EventState
EventState
State of handling an event.
Definition window_type.h:780
ES_HANDLED
@ ES_HANDLED
The passed event is handled.
Definition window_type.h:781
ES_NOT_HANDLED
@ ES_NOT_HANDLED
The passed event is not handled.
Definition window_type.h:782
GOID_NEWGRF_CURRENT_LOADED
@ GOID_NEWGRF_CURRENT_LOADED
The current list of active NewGRF has been loaded.
Definition window_type.h:742
GOID_NEWGRF_RESCANNED
@ GOID_NEWGRF_RESCANNED
NewGRFs were just rescanned.
Definition window_type.h:741
GOID_NEWGRF_CHANGES_MADE
@ GOID_NEWGRF_CHANGES_MADE
Changes have been made to a given NewGRF either through the palette or its parameters.
Definition window_type.h:744
GOID_NEWGRF_LIST_EDITED
@ GOID_NEWGRF_LIST_EDITED
List of active NewGRFs is being edited.
Definition window_type.h:743
WC_BUILD_OBJECT
@ WC_BUILD_OBJECT
Build object; Window numbers:
Definition window_type.h:381
WC_NONE
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition window_type.h:50
WC_SAVE_PRESET
@ WC_SAVE_PRESET
Save preset; Window numbers:
Definition window_type.h:709
WC_GAME_OPTIONS
@ WC_GAME_OPTIONS
Game options window; Window numbers:
Definition window_type.h:635
WC_TEXTFILE
@ WC_TEXTFILE
textfile; Window numbers:
Definition window_type.h:192
WC_DROPDOWN_MENU
@ WC_DROPDOWN_MENU
Drop down menu; Window numbers:
Definition window_type.h:161
WC_QUERY_STRING
@ WC_QUERY_STRING
Query string window; Window numbers:
Definition window_type.h:128
WC_GRF_PARAMETERS
@ WC_GRF_PARAMETERS
NewGRF parameters; Window numbers:
Definition window_type.h:186
WC_MODAL_PROGRESS
@ WC_MODAL_PROGRESS
Progress report of landscape generation; Window numbers:
Definition window_type.h:474
zoom_func.h
Functions related to zooming.