OpenTTD Source 20260129-master-g2bb01bd0e4
fios_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 "saveload/saveload.h"
12#include "error.h"
13#include "gui.h"
14#include "gfx_func.h"
15#include "command_func.h"
16#include "network/network.h"
18#include "strings_func.h"
19#include "fileio_func.h"
20#include "fios.h"
21#include "window_func.h"
22#include "tilehighlight_func.h"
23#include "querystring_gui.h"
24#include "engine_func.h"
25#include "landscape_type.h"
26#include "genworld.h"
29#include "gamelog.h"
30#include "stringfilter_type.h"
31#include "misc_cmd.h"
32#include "gamelog_internal.h"
33
34#include "widgets/fios_widget.h"
35
36#include "table/sprites.h"
37#include "table/strings.h"
38
39#include "safeguards.h"
40
42
43static bool _fios_path_changed;
44static bool _savegame_sort_dirty;
45
50{
51 this->checkable = false;
53 this->error_msg.clear();
54
55 this->map_size_x = this->map_size_y = 256; // Default for old savegames which do not store mapsize.
56 this->current_date = CalendarTime::MIN_DATE;
57 this->landscape = {};
58 this->starting_year = {};
59
60 companies.clear();
61
62 this->gamelog.Reset();
63
65}
66
68static constexpr std::initializer_list<NWidgetPart> _nested_load_dialog_widgets = {
70 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
71 NWidget(WWT_CAPTION, COLOUR_GREY, WID_SL_CAPTION),
72 NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
74 /* Current directory and free space */
75 NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_BACKGROUND), SetFill(1, 0), SetResize(1, 0),
77
79 /* Left side : filter box and available files */
81 /* Filter box with label */
82 NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), SetResize(1, 1),
85 NWidget(WWT_TEXT, INVALID_COLOUR), SetFill(0, 1), SetStringTip(STR_SAVELOAD_FILTER_TITLE),
86 NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SL_FILTER), SetFill(1, 0), SetResize(1, 0),
87 SetStringTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
90 /* Sort buttons */
93 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SORT_BYNAME), SetStringTip(STR_SORT_BY_CAPTION_NAME, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
94 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SORT_BYDATE), SetStringTip(STR_SORT_BY_CAPTION_DATE, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
96 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SL_HOME_BUTTON), SetAspect(1), SetSpriteTip(SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON_TOOLTIP),
98 /* Files */
101 NWidget(WWT_INSET, COLOUR_GREY, WID_SL_DRIVES_DIRECTORIES_LIST), SetFill(1, 1), SetPadding(2, 2, 2, 2),
102 SetToolTip(STR_SAVELOAD_LIST_TOOLTIP), SetResize(1, 10), SetScrollbar(WID_SL_SCROLLBAR),
103 EndContainer(),
104 EndContainer(),
106 EndContainer(),
107 /* Online Content button */
110 SetStringTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT),
111 EndContainer(),
112 EndContainer(),
113
114 /* Right side : game details */
116 NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_DETAILS), SetResize(1, 1), SetFill(1, 1),
117 EndContainer(),
118 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_MISSING_NEWGRFS), SetStringTip(STR_NEWGRF_SETTINGS_FIND_MISSING_CONTENT_BUTTON, STR_NEWGRF_SETTINGS_FIND_MISSING_CONTENT_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
121 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_NEWGRF_INFO), SetStringTip(STR_MAPGEN_NEWGRF_SETTINGS, STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
122 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_LOAD_BUTTON), SetStringTip(STR_SAVELOAD_LOAD_BUTTON, STR_SAVELOAD_LOAD_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
123 EndContainer(),
124 NWidget(WWT_RESIZEBOX, COLOUR_GREY),
125 EndContainer(),
126 EndContainer(),
127 EndContainer(),
128};
129
131static constexpr std::initializer_list<NWidgetPart> _nested_load_heightmap_dialog_widgets = {
133 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
134 NWidget(WWT_CAPTION, COLOUR_GREY, WID_SL_CAPTION),
135 NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
136 EndContainer(),
137 /* Current directory and free space */
138 NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_BACKGROUND), SetFill(1, 0), SetResize(1, 0),
139 EndContainer(),
140
141 /* Filter box with label */
142 NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), SetResize(1, 1),
145 NWidget(WWT_TEXT, INVALID_COLOUR), SetFill(0, 1), SetStringTip(STR_SAVELOAD_FILTER_TITLE),
146 NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SL_FILTER), SetFill(1, 0), SetResize(1, 0),
147 SetStringTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
148 EndContainer(),
149 EndContainer(),
150 /* Sort Buttons */
153 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SORT_BYNAME), SetStringTip(STR_SORT_BY_CAPTION_NAME, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
154 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SORT_BYDATE), SetStringTip(STR_SORT_BY_CAPTION_DATE, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
155 EndContainer(),
156 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SL_HOME_BUTTON), SetAspect(1), SetSpriteTip(SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON_TOOLTIP),
157 EndContainer(),
158 /* Files */
161 NWidget(WWT_INSET, COLOUR_GREY, WID_SL_DRIVES_DIRECTORIES_LIST), SetFill(1, 1), SetPadding(2, 2, 2, 2),
162 SetToolTip(STR_SAVELOAD_LIST_TOOLTIP), SetResize(1, 10), SetScrollbar(WID_SL_SCROLLBAR),
163 EndContainer(),
164 EndContainer(),
166 EndContainer(),
167 /* Online Content and Load button */
170 SetStringTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT),
171 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_LOAD_BUTTON), SetResize(1, 0), SetFill(1, 0),
172 SetStringTip(STR_SAVELOAD_LOAD_BUTTON, STR_SAVELOAD_LOAD_HEIGHTMAP_TOOLTIP),
173 NWidget(WWT_RESIZEBOX, COLOUR_GREY),
174 EndContainer(),
175};
176
178static constexpr std::initializer_list<NWidgetPart> _nested_load_town_data_dialog_widgets = {
180 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
181 NWidget(WWT_CAPTION, COLOUR_GREY, WID_SL_CAPTION),
182 NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
183 EndContainer(),
184 /* Current directory and free space */
185 NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_BACKGROUND), SetFill(1, 0), SetResize(1, 0), EndContainer(),
186
187 /* Filter box with label */
188 NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), SetResize(1, 1),
191 NWidget(WWT_TEXT, INVALID_COLOUR), SetFill(0, 1), SetStringTip(STR_SAVELOAD_FILTER_TITLE),
192 NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SL_FILTER), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
193 EndContainer(),
194 EndContainer(),
195 /* Sort Buttons */
198 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SORT_BYNAME), SetStringTip(STR_SORT_BY_CAPTION_NAME, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
199 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SORT_BYDATE), SetStringTip(STR_SORT_BY_CAPTION_DATE, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
200 EndContainer(),
201 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SL_HOME_BUTTON), SetAspect(1), SetSpriteTip(SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON_TOOLTIP),
202 EndContainer(),
203 /* Files */
206 NWidget(WWT_INSET, COLOUR_GREY, WID_SL_DRIVES_DIRECTORIES_LIST), SetFill(1, 1), SetPadding(2, 2, 2, 2),
207 SetToolTip(STR_SAVELOAD_LIST_TOOLTIP), SetResize(1, 10), SetScrollbar(WID_SL_SCROLLBAR), EndContainer(),
208 EndContainer(),
210 EndContainer(),
211 /* Load button */
213 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_LOAD_BUTTON), SetResize(1, 0), SetFill(1, 0),
214 SetStringTip(STR_SAVELOAD_LOAD_BUTTON, STR_SAVELOAD_LOAD_TOWN_DATA_TOOLTIP),
215 NWidget(WWT_RESIZEBOX, COLOUR_GREY),
216 EndContainer(),
217};
218
220static constexpr std::initializer_list<NWidgetPart> _nested_save_dialog_widgets = {
222 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
223 NWidget(WWT_CAPTION, COLOUR_GREY, WID_SL_CAPTION),
224 NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
225 EndContainer(),
226 /* Current directory and free space */
227 NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_BACKGROUND), SetFill(1, 0), SetResize(1, 0),
228 EndContainer(),
229
231 /* Left side : filter box and available files */
233 /* Filter box with label */
234 NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), SetResize(1, 1),
237 NWidget(WWT_TEXT, INVALID_COLOUR), SetFill(0, 1), SetStringTip(STR_SAVELOAD_FILTER_TITLE),
238 NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SL_FILTER), SetFill(1, 0), SetResize(1, 0),
239 SetStringTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
240 EndContainer(),
241 EndContainer(),
242 /* Sort buttons */
245 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SORT_BYNAME), SetStringTip(STR_SORT_BY_CAPTION_NAME, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
246 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SORT_BYDATE), SetStringTip(STR_SORT_BY_CAPTION_DATE, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
247 EndContainer(),
248 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SL_HOME_BUTTON), SetAspect(1), SetSpriteTip(SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON_TOOLTIP),
249 EndContainer(),
250 /* Files */
254 SetToolTip(STR_SAVELOAD_LIST_TOOLTIP), SetResize(1, 10), SetScrollbar(WID_SL_SCROLLBAR),
255 EndContainer(),
256 EndContainer(),
258 EndContainer(),
259 NWidget(WWT_PANEL, COLOUR_GREY),
260 NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SL_SAVE_OSK_TITLE), SetPadding(2, 2, 2, 2), SetFill(1, 0), SetResize(1, 0),
261 SetStringTip(STR_SAVELOAD_OSKTITLE, STR_SAVELOAD_EDITBOX_TOOLTIP),
262 EndContainer(),
263 /* Save/delete buttons */
265 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_DELETE_SELECTION), SetStringTip(STR_SAVELOAD_DELETE_BUTTON, STR_SAVELOAD_DELETE_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
266 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SAVE_GAME), SetStringTip(STR_SAVELOAD_SAVE_BUTTON, STR_SAVELOAD_SAVE_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
267 EndContainer(),
268 EndContainer(),
269
270 /* Right side : game details */
272 NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_DETAILS), SetResize(1, 1), SetFill(1, 1),
273 EndContainer(),
275 NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), SetFill(1, 1),
276 EndContainer(),
277 NWidget(WWT_RESIZEBOX, COLOUR_GREY),
278 EndContainer(),
279 EndContainer(),
280 EndContainer(),
281};
282
284static const TextColour _fios_colours[] = {
285 TC_LIGHT_BROWN, // DFT_OLD_GAME_FILE
286 TC_ORANGE, // DFT_GAME_FILE
287 TC_YELLOW, // DFT_HEIGHTMAP_BMP
288 TC_ORANGE, // DFT_HEIGHTMAP_PNG
289 TC_LIGHT_BROWN, // DFT_TOWN_DATA_JSON
290 TC_LIGHT_BLUE, // DFT_FIOS_DRIVE
291 TC_DARK_GREEN, // DFT_FIOS_PARENT
292 TC_DARK_GREEN, // DFT_FIOS_DIR
293 TC_ORANGE, // DFT_FIOS_DIRECT
294};
295/* This should align with the DetailedFileType enum defined in fileio_type.h */
296static_assert(std::size(_fios_colours) == DFT_END);
297
302static void SortSaveGameList(FileList &file_list)
303{
304 size_t sort_start = 0;
305 size_t sort_end = 0;
306
307 /* Directories are always above the files (FIOS_TYPE_DIR)
308 * Drives (A:\ (windows only) are always under the files (FIOS_TYPE_DRIVE)
309 * Only sort savegames/scenarios, not directories
310 */
311 for (const auto &item : file_list) {
312 switch (item.type.detailed) {
313 case DFT_FIOS_DIR: sort_start++; break;
314 case DFT_FIOS_PARENT: sort_start++; break;
315 case DFT_FIOS_DRIVE: sort_end++; break;
316 default: break;
317 }
318 }
319
320 std::sort(file_list.begin() + sort_start, file_list.end() - sort_end);
321}
322
323struct SaveLoadWindow : public Window {
324private:
325 static const uint EDITBOX_MAX_SIZE = 50;
326
328 AbstractFileType abstract_filetype{};
332 const FiosItem *selected = nullptr;
333 const FiosItem *highlighted = nullptr;
334 Scrollbar *vscroll = nullptr;
335
338 std::vector<FiosItem *> display_list{};
339
340 static void SaveGameConfirmationCallback(Window *, bool confirmed)
341 {
342 /* File name has already been written to _file_to_saveload */
343 if (confirmed) _switch_mode = SM_SAVE_GAME;
344 }
345
346 static void SaveHeightmapConfirmationCallback(Window *, bool confirmed)
347 {
348 /* File name has already been written to _file_to_saveload */
349 if (confirmed) _switch_mode = SM_SAVE_HEIGHTMAP;
350 }
351
352 static void DeleteFileConfirmationCallback(Window *window, bool confirmed)
353 {
354 auto *save_load_window = static_cast<SaveLoadWindow*>(window);
355
356 assert(save_load_window->selected != nullptr);
357
358 if (confirmed) {
359 if (!FioRemove(save_load_window->selected->name)) {
360 ShowErrorMessage(GetEncodedString(STR_ERROR_UNABLE_TO_DELETE_FILE), {}, WL_ERROR);
361 } else {
362 save_load_window->InvalidateData(SLIWD_RESCAN_FILES);
363 /* Reset file name to current date on successful delete */
364 if (save_load_window->abstract_filetype == FT_SAVEGAME) save_load_window->GenerateFileName();
365 }
366 }
367 }
368
369public:
370
373 {
374 this->filename_editbox.text.Assign(GenerateDefaultSaveName());
375 }
376
378 : Window(desc), filename_editbox(64), abstract_filetype(abstract_filetype), fop(fop), filter_editbox(EDITBOX_MAX_SIZE)
379 {
380 assert(this->fop == SLO_SAVE || this->fop == SLO_LOAD);
381
382 /* For saving, construct an initial file name. */
383 if (this->fop == SLO_SAVE) {
384 switch (this->abstract_filetype) {
385 case FT_SAVEGAME:
386 this->GenerateFileName();
387 break;
388
389 case FT_SCENARIO:
390 case FT_HEIGHTMAP:
391 this->filename_editbox.text.Assign("UNNAMED");
392 break;
393
394 default:
395 /* It's not currently possible to save town data. */
396 NOT_REACHED();
397 }
398 }
400 this->filename_editbox.ok_button = WID_SL_SAVE_GAME;
401
402 this->CreateNestedTree();
403 if (this->fop == SLO_LOAD && this->abstract_filetype == FT_SAVEGAME) {
404 this->GetWidget<NWidgetStacked>(WID_SL_CONTENT_DOWNLOAD_SEL)->SetDisplayedPlane(SZSP_HORIZONTAL);
405 }
406
407 /* Select caption string of the window. */
408 StringID caption_string;
409 switch (this->abstract_filetype) {
410 case FT_SAVEGAME:
411 caption_string = (this->fop == SLO_SAVE) ? STR_SAVELOAD_SAVE_CAPTION : STR_SAVELOAD_LOAD_CAPTION;
412 break;
413
414 case FT_SCENARIO:
415 caption_string = (this->fop == SLO_SAVE) ? STR_SAVELOAD_SAVE_SCENARIO : STR_SAVELOAD_LOAD_SCENARIO;
416 break;
417
418 case FT_HEIGHTMAP:
419 caption_string = (this->fop == SLO_SAVE) ? STR_SAVELOAD_SAVE_HEIGHTMAP : STR_SAVELOAD_LOAD_HEIGHTMAP;
420 break;
421
422 case FT_TOWN_DATA:
423 caption_string = STR_SAVELOAD_LOAD_TOWN_DATA; // It's not currently possible to save town data.
424 break;
425
426 default:
427 NOT_REACHED();
428 }
429 this->GetWidget<NWidgetCore>(WID_SL_CAPTION)->SetString(caption_string);
430
431 this->vscroll = this->GetScrollbar(WID_SL_SCROLLBAR);
432 this->FinishInitNested(0);
433
436 this->filter_editbox.cancel_button = QueryString::ACTION_CLEAR;
437
438 /* pause is only used in single-player, non-editor mode, non-menu mode. It
439 * will be unpaused in the WE_DESTROY event handler. */
440 if (_game_mode != GM_MENU && !_networking && _game_mode != GM_EDITOR) {
442 }
443 SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0);
444
446
448
449 /* Select the initial directory. */
450 o_dir.type = FIOS_TYPE_DIRECT;
451 switch (this->abstract_filetype) {
452 case FT_SAVEGAME:
453 o_dir.name = FioFindDirectory(SAVE_DIR);
454 break;
455
456 case FT_SCENARIO:
457 o_dir.name = FioFindDirectory(SCENARIO_DIR);
458 break;
459
460 case FT_HEIGHTMAP:
461 case FT_TOWN_DATA:
462 o_dir.name = FioFindDirectory(HEIGHTMAP_DIR);
463 break;
464
465 default:
466 o_dir.name = _personal_dir;
467 }
468
469 switch (this->fop) {
470 case SLO_SAVE:
471 /* Focus the edit box by default in the save window */
473 break;
474
475 default:
477 }
478 }
479
480 void Close([[maybe_unused]] int data = 0) override
481 {
482 /* pause is only used in single-player, non-editor mode, non menu mode */
483 if (!_networking && _game_mode != GM_EDITOR && _game_mode != GM_MENU) {
485 }
486 this->Window::Close();
487 }
488
489 void DrawWidget(const Rect &r, WidgetID widget) const override
490 {
491 switch (widget) {
494 if (((_savegame_sort_order & SORT_BY_NAME) != 0) == (widget == WID_SL_SORT_BYNAME)) {
495 this->DrawSortButtonState(widget, _savegame_sort_order & SORT_DESCENDING ? SBS_DOWN : SBS_UP);
496 }
497 break;
498
499 case WID_SL_BACKGROUND: {
500 static std::string path;
501 static std::optional<uint64_t> free_space = std::nullopt;
502
503 if (_fios_path_changed) {
504 path = FiosGetCurrentPath();
505 free_space = FiosGetDiskFreeSpace(path);
506 _fios_path_changed = false;
507 }
508
509 Rect ir = r.Shrink(WidgetDimensions::scaled.framerect);
510
511 if (free_space.has_value()) {
512 DrawString(ir.left, ir.right, ir.top + GetCharacterHeight(FS_NORMAL), GetString(STR_SAVELOAD_BYTES_FREE, free_space.value()));
513 } else {
514 DrawString(ir.left, ir.right, ir.top + GetCharacterHeight(FS_NORMAL), STR_ERROR_UNABLE_TO_READ_DRIVE);
515 }
516 DrawString(ir.left, ir.right, ir.top, path, TC_BLACK);
517 break;
518 }
519
521 const Rect br = r.Shrink(WidgetDimensions::scaled.bevel);
523
525 auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->display_list);
526 for (auto it = first; it != last; ++it) {
527 const FiosItem *item = *it;
528
529 if (item == this->selected) {
531 } else if (item == this->highlighted) {
533 }
534 DrawString(tr, item->title.GetDecodedString(), _fios_colours[item->type.detailed]);
535 tr = tr.Translate(0, this->resize.step_height);
536 }
537 break;
538 }
539
540 case WID_SL_DETAILS:
541 this->DrawDetails(r);
542 break;
543 }
544 }
545
546 void DrawDetails(const Rect &r) const
547 {
548 /* Header panel */
550
551 Rect hr = r.WithHeight(HEADER_HEIGHT).Shrink(WidgetDimensions::scaled.frametext);
552 Rect tr = r.Shrink(WidgetDimensions::scaled.frametext);
553 tr.top += HEADER_HEIGHT;
554
555 /* Create the nice lighter rectangle at the details top */
557 DrawString(hr.left, hr.right, hr.top, STR_SAVELOAD_DETAIL_CAPTION, TC_FROMSTRING, SA_HOR_CENTER);
558
559 if (this->selected == nullptr) return;
560
561 /* Details panel */
562 tr.bottom -= GetCharacterHeight(FS_NORMAL) - 1;
563 if (tr.top > tr.bottom) return;
564
566 /* Old savegame, no information available */
567 DrawString(tr, STR_SAVELOAD_DETAIL_NOT_AVAILABLE);
568 tr.top += GetCharacterHeight(FS_NORMAL);
570 /* Incompatible / broken savegame */
572 } else {
573 /* Mapsize */
574 DrawString(tr, GetString(STR_NETWORK_SERVER_LIST_MAP_SIZE, _load_check_data.map_size_x, _load_check_data.map_size_y));
575 tr.top += GetCharacterHeight(FS_NORMAL);
576 if (tr.top > tr.bottom) return;
577
578 /* Climate */
579 if (to_underlying(_load_check_data.landscape) < NUM_LANDSCAPE) {
580 DrawString(tr, GetString(STR_NETWORK_SERVER_LIST_LANDSCAPE, STR_CLIMATE_TEMPERATE_LANDSCAPE + to_underlying(_load_check_data.landscape)));
581 tr.top += GetCharacterHeight(FS_NORMAL);
582 }
583
585 if (tr.top > tr.bottom) return;
586
587 /* Start date (if available) */
589 DrawString(tr, GetString(STR_NETWORK_SERVER_LIST_START_DATE, TimerGameCalendar::ConvertYMDToDate(_load_check_data.starting_year, 0, 1)));
590 tr.top += GetCharacterHeight(FS_NORMAL);
591 }
592 if (tr.top > tr.bottom) return;
593
594 /* Hide current date for scenarios */
595 if (this->abstract_filetype != FT_SCENARIO) {
596 /* Current date */
597 DrawString(tr, GetString(STR_NETWORK_SERVER_LIST_CURRENT_DATE, _load_check_data.current_date));
598 tr.top += GetCharacterHeight(FS_NORMAL);
599 }
600
601 /* Hide the NewGRF stuff when saving. We also hide the button. */
602 if (this->fop == SLO_LOAD && (this->abstract_filetype == FT_SAVEGAME || this->abstract_filetype == FT_SCENARIO)) {
604 if (tr.top > tr.bottom) return;
605
606 /* NewGrf compatibility */
607 DrawString(tr, GetString(STR_SAVELOAD_DETAIL_GRFSTATUS, _load_check_data.grfconfig.empty() ? STR_NEWGRF_LIST_NONE : STR_NEWGRF_LIST_ALL_FOUND + _load_check_data.grf_compatibility));
608 tr.top += GetCharacterHeight(FS_NORMAL);
609 }
610 if (tr.top > tr.bottom) return;
611
612 /* Hide the company stuff for scenarios */
613 if (this->abstract_filetype != FT_SCENARIO) {
615 if (tr.top > tr.bottom) return;
616
617 /* Companies / AIs */
618 for (auto &pair : _load_check_data.companies) {
619 const CompanyProperties &c = *pair.second;
620 if (c.name.empty()) {
622 DrawString(tr, GetString(STR_SAVELOAD_DETAIL_COMPANY_INDEX, pair.first + 1, c.name_1, c.name_2));
623 } else {
624 DrawString(tr, GetString(STR_SAVELOAD_DETAIL_COMPANY_INDEX, pair.first + 1, STR_JUST_RAW_STRING, c.name));
625 }
626
627 tr.top += GetCharacterHeight(FS_NORMAL);
628 if (tr.top > tr.bottom) break;
629 }
630 }
631 }
632 }
633
634 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
635 {
636 switch (widget) {
638 size.height = 2 * GetCharacterHeight(FS_NORMAL) + padding.height;
639 break;
640
642 fill.height = resize.height = GetCharacterHeight(FS_NORMAL);
643 size.height = resize.height * 10 + padding.height;
644 break;
646 case WID_SL_SORT_BYDATE: {
647 Dimension d = GetStringBoundingBox(this->GetWidget<NWidgetCore>(widget)->GetString());
648 d.width += padding.width + Window::SortButtonWidth() * 2; // Doubled since the string is centred and it also looks better.
649 d.height += padding.height;
650 size = maxdim(size, d);
651 break;
652 }
653 }
654 }
655
656 void OnPaint() override
657 {
658 if (_savegame_sort_dirty) {
659 _savegame_sort_dirty = false;
662 }
663
664 this->DrawWidgets();
665 }
666
667 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
668 {
669 switch (widget) {
670 case WID_SL_SORT_BYNAME: // Sort save names by name
671 _savegame_sort_order = (_savegame_sort_order == SORT_BY_NAME) ?
672 SORT_BY_NAME | SORT_DESCENDING : SORT_BY_NAME;
673 _savegame_sort_dirty = true;
674 this->SetDirty();
675 break;
676
677 case WID_SL_SORT_BYDATE: // Sort save names by date
678 _savegame_sort_order = (_savegame_sort_order == SORT_BY_DATE) ?
679 SORT_BY_DATE | SORT_DESCENDING : SORT_BY_DATE;
680 _savegame_sort_dirty = true;
681 this->SetDirty();
682 break;
683
684 case WID_SL_HOME_BUTTON: // OpenTTD 'button', jumps to OpenTTD directory
687 break;
688
689 case WID_SL_LOAD_BUTTON: {
690 if (this->selected == nullptr || _load_check_data.HasErrors()) break;
691
692 _file_to_saveload.Set(*this->selected);
693
694 if (this->abstract_filetype == FT_HEIGHTMAP) {
695 this->Close();
697 } else if (this->abstract_filetype == FT_TOWN_DATA) {
698 this->Close();
699 LoadTownData();
701 _switch_mode = (_game_mode == GM_EDITOR) ? SM_LOAD_SCENARIO : SM_LOAD_GAME;
703 this->Close();
704 }
705 break;
706 }
707
709 if (_load_check_data.HasNewGrfs()) {
710 ShowNewGRFSettings(false, false, false, _load_check_data.grfconfig);
711 }
712 break;
713
715 if (!_network_available) {
716 ShowErrorMessage(GetEncodedString(STR_NETWORK_ERROR_NOTAVAILABLE), {}, WL_ERROR);
717 } else if (_load_check_data.HasNewGrfs()) {
719 }
720 break;
721
722 case WID_SL_DRIVES_DIRECTORIES_LIST: { // Click the listbox
724 if (it == this->display_list.end()) return;
725
726 /* Get the corresponding non-filtered out item from the list */
727 const FiosItem *file = *it;
728
729 if (FiosBrowseTo(file)) {
730 /* Changed directory, need refresh. */
732 break;
733 }
734
735 if (click_count == 1) {
736 if (this->selected != file) {
737 this->selected = file;
739
740 if (file->type.detailed == DFT_GAME_FILE) {
741 /* Other detailed file types cannot be checked before. */
742 SaveOrLoad(file->name, SLO_CHECK, DFT_GAME_FILE, NO_DIRECTORY, false);
743 }
744
746 }
747 if (this->fop == SLO_SAVE) {
748 /* Copy clicked name to editbox */
749 this->filename_editbox.text.Assign(file->title.GetDecodedString());
751 }
752 } else if (!_load_check_data.HasErrors()) {
753 this->selected = file;
754 if (this->fop == SLO_LOAD) {
755 if (this->abstract_filetype == FT_SAVEGAME || this->abstract_filetype == FT_SCENARIO || this->abstract_filetype == FT_TOWN_DATA) {
756 this->OnClick(pt, WID_SL_LOAD_BUTTON, 1);
757 } else {
758 assert(this->abstract_filetype == FT_HEIGHTMAP);
759 _file_to_saveload.Set(*file);
760
761 this->Close();
763 }
764 }
765 }
766 break;
767 }
768
770 if (!_network_available) {
771 ShowErrorMessage(GetEncodedString(STR_NETWORK_ERROR_NOTAVAILABLE), {}, WL_ERROR);
772 } else {
773 assert(this->fop == SLO_LOAD);
774 switch (this->abstract_filetype) {
775 default: NOT_REACHED();
778 }
779 }
780 break;
781
782 case WID_SL_DELETE_SELECTION: // Delete
783 break;
784
785 case WID_SL_SAVE_GAME: // Save game
786 /* Note, this is also called via the OSK; and we need to lower the button. */
788 break;
789 }
790 }
791
792 void OnMouseOver([[maybe_unused]] Point pt, WidgetID widget) override
793 {
794 if (widget == WID_SL_DRIVES_DIRECTORIES_LIST) {
796 if (it == this->display_list.end()) return;
797
798 /* Get the corresponding non-filtered out item from the list */
799 const FiosItem *file = *it;
800
801 if (file != this->highlighted) {
802 this->highlighted = file;
804 }
805 } else if (this->highlighted != nullptr) {
806 this->highlighted = nullptr;
808 }
809 }
810
811 EventState OnKeyPress([[maybe_unused]] char32_t key, uint16_t keycode) override
812 {
813 if (keycode == WKC_ESC) {
814 this->Close();
815 return ES_HANDLED;
816 }
817
818 return ES_NOT_HANDLED;
819 }
820
821 void OnTimeout() override
822 {
823 /* Widgets WID_SL_DELETE_SELECTION and WID_SL_SAVE_GAME only exist when saving to a file. */
824 if (this->fop != SLO_SAVE) return;
825
826 if (this->IsWidgetLowered(WID_SL_DELETE_SELECTION)) { // Delete button clicked
827 ShowQuery(GetEncodedString(STR_SAVELOAD_DELETE_TITLE), GetEncodedString(STR_SAVELOAD_DELETE_WARNING),
828 this, SaveLoadWindow::DeleteFileConfirmationCallback);
829 } else if (this->IsWidgetLowered(WID_SL_SAVE_GAME)) { // Save button clicked
830 if (this->abstract_filetype == FT_SAVEGAME || this->abstract_filetype == FT_SCENARIO) {
831 _file_to_saveload.name = FiosMakeSavegameName(this->filename_editbox.text.GetText());
833 ShowQuery(GetEncodedString(STR_SAVELOAD_OVERWRITE_TITLE), GetEncodedString(STR_SAVELOAD_OVERWRITE_WARNING),
834 this, SaveLoadWindow::SaveGameConfirmationCallback);
835 } else {
837 }
838 } else {
839 _file_to_saveload.name = FiosMakeHeightmapName(this->filename_editbox.text.GetText());
841 ShowQuery(GetEncodedString(STR_SAVELOAD_OVERWRITE_TITLE), GetEncodedString(STR_SAVELOAD_OVERWRITE_WARNING),
842 this, SaveLoadWindow::SaveHeightmapConfirmationCallback);
843 } else {
845 }
846 }
847
848 /* In the editor set up the vehicle engines correctly (date might have changed) */
849 if (_game_mode == GM_EDITOR) StartupEngines();
850 }
851 }
852
853 void OnResize() override
854 {
856 }
857
858 void BuildDisplayList()
859 {
860 /* Filter changes */
861 this->display_list.clear();
862 this->display_list.reserve(this->fios_items.size());
863
864 if (this->string_filter.IsEmpty()) {
865 /* We don't filter anything out if the filter editbox is empty */
866 for (auto &it : this->fios_items) {
867 this->display_list.push_back(&it);
868 }
869 } else {
870 for (auto &it : this->fios_items) {
872 this->string_filter.AddLine(it.title.GetDecodedString());
873 /* We set the vector to show this fios element as filtered depending on the result of the filter */
874 if (this->string_filter.GetState()) {
875 this->display_list.push_back(&it);
876 } else if (&it == this->selected) {
877 /* The selected element has been filtered out */
878 this->selected = nullptr;
880 }
881 }
882 }
883
884 this->vscroll->SetCount(this->display_list.size());
885 }
886
892 void OnInvalidateData(int data = 0, bool gui_scope = true) override
893 {
894 switch (data) {
896 /* Rescan files */
897 this->selected = nullptr;
899 if (!gui_scope) break;
900
901 _fios_path_changed = true;
902 this->fios_items.BuildFileList(this->abstract_filetype, this->fop, true);
903 this->selected = nullptr;
905
906 /* We reset the files filtered */
908
909 [[fallthrough]];
910
912 /* Selection changes */
913 if (!gui_scope) break;
914
915 if (this->fop == SLO_SAVE) this->SetWidgetDisabledState(WID_SL_DELETE_SELECTION, this->selected == nullptr);
916
917 if (this->fop != SLO_LOAD) break;
918
919 switch (this->abstract_filetype) {
920 case FT_HEIGHTMAP:
921 case FT_TOWN_DATA:
922 this->SetWidgetDisabledState(WID_SL_LOAD_BUTTON, this->selected == nullptr || _load_check_data.HasErrors());
923 break;
924
925 case FT_SAVEGAME:
926 case FT_SCENARIO: {
927 bool disabled = this->selected == nullptr || _load_check_data.HasErrors();
930 }
932 this->SetWidgetDisabledState(WID_SL_NEWGRF_INFO, !_load_check_data.HasNewGrfs());
935 break;
936 }
937
938 default:
939 NOT_REACHED();
940 }
941 break;
942
944 this->BuildDisplayList();
945 break;
946 }
947 }
948
949 void OnEditboxChanged(WidgetID wid) override
950 {
951 if (wid == WID_SL_FILTER) {
952 this->string_filter.SetFilterTerm(this->filter_editbox.text.GetText());
954 }
955
956 if (wid == WID_SL_SAVE_OSK_TITLE) {
957 this->selected = nullptr;
959 }
960 }
961};
962
965 WDP_CENTER, "load_game", 500, 294,
967 {},
969);
970
973 WDP_CENTER, "load_heightmap", 257, 320,
975 {},
977);
978
981 WDP_CENTER, "load_town_data", 257, 320,
983 {},
985);
986
989 WDP_CENTER, "save_game", 500, 294,
991 {},
993);
994
1001{
1003
1004 if (fop == SLO_SAVE) {
1005 new SaveLoadWindow(_save_dialog_desc, abstract_filetype, fop);
1006 } else {
1007 /* Dialogue for loading a file. */
1008 switch (abstract_filetype) {
1009 case FT_HEIGHTMAP:
1010 new SaveLoadWindow(_load_heightmap_dialog_desc, abstract_filetype, fop);
1011 break;
1012
1013 case FT_TOWN_DATA:
1014 new SaveLoadWindow(_load_town_data_dialog_desc, abstract_filetype, fop);
1015 break;
1016
1017 default:
1018 new SaveLoadWindow(_load_dialog_desc, abstract_filetype, fop);
1019 }
1020 }
1021}
std::string GetDecodedString() const
Decode the encoded string.
Definition strings.cpp:207
List of file information.
Definition fios.h:87
void BuildFileList(AbstractFileType abstract_filetype, SaveLoadOperation fop, bool show_dirs)
Construct a file list with the given kind of files, for the stated purpose.
Definition fios.cpp:64
void Reset()
Resets and frees all memory allocated - used before loading or starting a new game.
Definition gamelog.cpp:94
Scrollbar data structure.
void SetCount(size_t num)
Sets the number of elements in the list.
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.
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
auto GetVisibleRangeIterators(Tcontainer &container) const
Get a pair of iterators for the range of visible elements in a container.
static Date ConvertYMDToDate(Year year, Month month, Day day)
Converts a tuple of Year, Month and Day to a Date.
static constexpr TimerGame< struct Calendar >::Date MIN_DATE
The date on January 1, year 0.
RectPadding framerect
Standard padding inside many panels.
Definition window_gui.h:40
RectPadding frametext
Padding inside frame with text.
Definition window_gui.h:41
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition window_gui.h:30
int vsep_normal
Normal vertical spacing.
Definition window_gui.h:58
int vsep_wide
Wide vertical spacing.
Definition window_gui.h:60
RectPadding inset
Padding inside inset container.
Definition window_gui.h:35
static const WidgetDimensions unscaled
Unscaled widget dimensions.
Definition window_gui.h:93
RectPadding bevel
Bevel thickness, affected by "scaled bevels" game option.
Definition window_gui.h:38
Functions related to commands.
void StartupEngines()
Start/initialise all our engines.
Definition engine.cpp:802
Functions related to engines.
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23)
Definition enum_type.hpp:17
Functions related to errors.
void ClearErrorMessages()
Clear all errors from the queue.
@ WL_ERROR
Errors (eg. saving/loading failed)
Definition error.h:26
void ShowErrorMessage(EncodedString &&summary_msg, int x, int y, CommandCost &cc)
Display an error message in a window.
bool FioRemove(const std::string &filename)
Remove a file.
Definition fileio.cpp:327
std::string _personal_dir
custom directory for personal settings, saves, newgrf, etc.
Definition fileio.cpp:871
bool FioCheckFileExists(std::string_view filename, Subdirectory subdir)
Check whether the given file exists.
Definition fileio.cpp:121
Functions for standard in/out file operations.
SaveLoadOperation
Operation performed on the file.
Definition fileio_type.h:52
@ SLO_CHECK
Load file for checking and/or preview.
Definition fileio_type.h:53
@ SLO_SAVE
File is being saved.
Definition fileio_type.h:55
@ SLO_LOAD
File is being loaded.
Definition fileio_type.h:54
@ DFT_FIOS_DRIVE
A drive (letter) entry.
Definition fileio_type.h:41
@ DFT_GAME_FILE
Save game or scenario file.
Definition fileio_type.h:31
@ DFT_FIOS_DIR
A directory entry.
Definition fileio_type.h:43
@ DFT_FIOS_PARENT
A parent directory entry.
Definition fileio_type.h:42
@ DFT_END
End of this enum. Supports a compile time size check against _fios_colours in fios_gui....
Definition fileio_type.h:46
@ NO_DIRECTORY
A path without any base directory.
@ SCENARIO_DIR
Base directory for all scenarios.
Definition fileio_type.h:92
@ SAVE_DIR
Base directory for all savegames.
Definition fileio_type.h:90
@ HEIGHTMAP_DIR
Subdirectory of scenario for heightmaps.
Definition fileio_type.h:93
AbstractFileType
The different abstract types of files that the system knows about.
Definition fileio_type.h:17
@ FT_SCENARIO
old or new scenario
Definition fileio_type.h:20
@ FT_HEIGHTMAP
heightmap file
Definition fileio_type.h:21
@ FT_SAVEGAME
old or new savegame
Definition fileio_type.h:19
@ FT_TOWN_DATA
town data file
Definition fileio_type.h:22
std::string FiosMakeSavegameName(std::string_view name)
Make a save game or scenario filename from a name.
Definition fios.cpp:213
std::string FiosGetCurrentPath()
Get the current path/working directory.
Definition fios.cpp:129
std::string FiosMakeHeightmapName(std::string_view name)
Construct a filename for a height map.
Definition fios.cpp:225
bool FiosBrowseTo(const FiosItem *item)
Browse to a new path based on the passed item, starting at _fios_path.
Definition fios.cpp:139
Declarations for savegames operations.
@ SLIWD_FILTER_CHANGES
The filename filter has changed (via the editbox)
Definition fios.h:25
@ SLIWD_SELECTION_CHANGES
File selection has changed (user click, ...)
Definition fios.h:24
@ SLIWD_RESCAN_FILES
Rescan all files (when changed directory, ...)
Definition fios.h:23
void ShowSaveLoadDialog(AbstractFileType abstract_filetype, SaveLoadOperation fop)
Launch save/load dialog in the given mode.
static WindowDesc _load_town_data_dialog_desc(WDP_CENTER, "load_town_data", 257, 320, WC_SAVELOAD, WC_NONE, {}, _nested_load_town_data_dialog_widgets)
Load town data.
static constexpr std::initializer_list< NWidgetPart > _nested_save_dialog_widgets
Save game/scenario.
Definition fios_gui.cpp:220
static constexpr std::initializer_list< NWidgetPart > _nested_load_heightmap_dialog_widgets
Load heightmap with content download.
Definition fios_gui.cpp:131
static constexpr std::initializer_list< NWidgetPart > _nested_load_dialog_widgets
Load game/scenario with optional content download.
Definition fios_gui.cpp:68
static WindowDesc _load_heightmap_dialog_desc(WDP_CENTER, "load_heightmap", 257, 320, WC_SAVELOAD, WC_NONE, {}, _nested_load_heightmap_dialog_widgets)
Load heightmap.
static WindowDesc _load_dialog_desc(WDP_CENTER, "load_game", 500, 294, WC_SAVELOAD, WC_NONE, {}, _nested_load_dialog_widgets)
Load game/scenario.
static WindowDesc _save_dialog_desc(WDP_CENTER, "save_game", 500, 294, WC_SAVELOAD, WC_NONE, {}, _nested_save_dialog_widgets)
Save game/scenario.
static constexpr std::initializer_list< NWidgetPart > _nested_load_town_data_dialog_widgets
Load town data.
Definition fios_gui.cpp:178
LoadCheckData _load_check_data
Data loaded from save during SL_LOAD_CHECK.
Definition fios_gui.cpp:41
static const TextColour _fios_colours[]
Text colours of DetailedFileType fios entries in the window.
Definition fios_gui.cpp:284
static void SortSaveGameList(FileList &file_list)
Sort the collected list save games prior to displaying it in the save/load gui.
Definition fios_gui.cpp:302
Types related to the fios widgets.
@ WID_SL_SORT_BYDATE
Sort by date button.
Definition fios_widget.h:17
@ WID_SL_SAVE_GAME
Save button, only available for save operations.
Definition fios_widget.h:27
@ WID_SL_BACKGROUND
Background of window.
Definition fios_widget.h:19
@ WID_SL_SAVE_OSK_TITLE
Title textbox, only available for save operations.
Definition fios_widget.h:25
@ WID_SL_DELETE_SELECTION
Delete button, only available for save operations.
Definition fios_widget.h:26
@ WID_SL_DETAILS
Panel with game details.
Definition fios_widget.h:29
@ WID_SL_FILE_BACKGROUND
Background of file selection.
Definition fios_widget.h:20
@ WID_SL_NEWGRF_INFO
Button to open NewGgrf configuration.
Definition fios_widget.h:30
@ WID_SL_DRIVES_DIRECTORIES_LIST
Drives list.
Definition fios_widget.h:22
@ WID_SL_LOAD_BUTTON
Button to load game/scenario.
Definition fios_widget.h:31
@ WID_SL_FILTER
Filter list of files.
Definition fios_widget.h:18
@ WID_SL_SCROLLBAR
Scrollbar of the file list.
Definition fios_widget.h:23
@ WID_SL_CAPTION
Caption of the window.
Definition fios_widget.h:15
@ WID_SL_HOME_BUTTON
Home button.
Definition fios_widget.h:21
@ WID_SL_SORT_BYNAME
Sort by name button.
Definition fios_widget.h:16
@ WID_SL_MISSING_NEWGRFS
Button to find missing NewGRFs online.
Definition fios_widget.h:32
@ WID_SL_CONTENT_DOWNLOAD_SEL
Selection 'stack' to 'hide' the content download.
Definition fios_widget.h:28
@ WID_SL_CONTENT_DOWNLOAD
Content download button, only available for play scenario/heightmap.
Definition fios_widget.h:24
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition fontcache.cpp:87
Functions to be called to log fundamental changes to the game.
Declaration shared among gamelog.cpp and saveload/gamelog_sl.cpp.
void LoadTownData()
Load town data from _file_to_saveload, place towns at the appropriate locations, and expand them to t...
Definition genworld.cpp:359
Functions related to world/map generation.
void ShowHeightmapLoad()
Start with loading a heightmap.
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
Geometry functions.
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition gfx.cpp:897
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:668
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:785
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
SwitchMode _switch_mode
The next mainloop command.
Definition gfx.cpp:49
Functions related to the gfx engine.
@ FS_NORMAL
Index of the normal font in the font tables.
Definition gfx_type.h:249
@ SA_HOR_CENTER
Horizontally center the text.
Definition gfx_type.h:389
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
Definition gfx_type.h:307
constexpr NWidgetPart SetFill(uint16_t fill_x, uint16_t fill_y)
Widget part function for setting filling.
constexpr NWidgetPart SetSpriteTip(SpriteID sprite, StringID tip={})
Widget part function for setting the sprite and tooltip.
constexpr NWidgetPart SetPIP(uint8_t pre, uint8_t inter, uint8_t post)
Widget part function for setting a pre/inter/post spaces.
constexpr NWidgetPart SetScrollbar(WidgetID index)
Attach a scrollbar to a widget.
constexpr NWidgetPart SetPadding(uint8_t top, uint8_t right, uint8_t bottom, uint8_t left)
Widget part function for setting additional space around a widget.
constexpr NWidgetPart SetStringTip(StringID string, StringID tip={})
Widget part function for setting the string and tooltip.
constexpr NWidgetPart SetAspect(float ratio, AspectFlags flags=AspectFlag::ResizeX)
Widget part function for setting the aspect ratio.
constexpr NWidgetPart SetToolTip(StringID tip)
Widget part function for setting tooltip and clearing the widget data.
constexpr NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx=INVALID_WIDGET)
Widget part function for starting a new 'real' widget.
constexpr NWidgetPart SetResize(int16_t dx, int16_t dy)
Widget part function for setting the resize step.
void SetDirty() const
Mark entire window as dirty (in need of re-paint)
Definition window.cpp:968
GUI functions that shouldn't be here.
Types related to the landscape.
Miscellaneous command definitions.
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...
bool _network_available
is network mode available?
Definition network.cpp:68
bool _networking
are we in networking mode?
Definition network.cpp:66
Basic functions/variables used all over the place.
Part of the network protocol handling content distribution.
void ShowNetworkContentListWindow(ContentVector *cv=nullptr, ContentType type1=CONTENT_TYPE_END, ContentType type2=CONTENT_TYPE_END)
Show the content list window with a given set of content.
void ShowMissingContentWindow(const GRFConfigList &list)
Show the content list window with all missing grfs from the given list.
void ClearGRFConfigList(GRFConfigList &config)
Clear a GRF Config list, freeing all nodes.
@ GLC_ALL_GOOD
All GRF needed by game are present.
@ GLC_NOT_FOUND
At least one GRF couldn't be found (higher priority than GLC_COMPATIBLE)
void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfigList &config)
Setup the NewGRF gui.
@ SaveLoad
A game paused for saving/loading.
@ SM_LOAD_SCENARIO
Load scenario from scenario editor.
Definition openttd.h:37
@ SM_SAVE_HEIGHTMAP
Save heightmap.
Definition openttd.h:35
@ SM_SAVE_GAME
Save game.
Definition openttd.h:34
@ SM_LOAD_GAME
Load game, Play Scenario.
Definition openttd.h:32
PixelColour GetColourGradient(Colours colour, ColourShade shade)
Get colour gradient palette index.
Definition palette.cpp:388
static constexpr PixelColour PC_DARK_BLUE
Dark blue palette colour.
static constexpr PixelColour PC_BLACK
Black palette colour.
static constexpr PixelColour PC_VERY_DARK_BLUE
Almost-black blue palette colour.
Base for the GUIs that have an edit box in them.
A number of safeguards to prevent using unsafe methods.
SaveOrLoadResult SaveOrLoad(std::string_view filename, SaveLoadOperation fop, DetailedFileType dft, Subdirectory sb, bool threaded)
Main Save or Load function where the high-level saveload functions are handled.
FileToSaveLoad _file_to_saveload
File to save or load in the openttd loop.
Definition saveload.cpp:78
std::string GenerateDefaultSaveName()
Get the default name for a savegame or screenshot.
Functions/types related to saving and loading games.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:60
This file contains all sprite-related enums and defines.
Definition of base types and functions in a cross-platform compatible way.
Searching and filtering using a stringterm.
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
Definition strings.cpp:90
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
Definition strings.cpp:424
Functions related to OTTD's strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
Class to backup a specific variable and restore it upon destruction of this object to prevent stack v...
GUISettings gui
settings related to the GUI
Statically loadable part of Company pool item.
uint32_t name_2
Parameter of name_1.
StringID name_1
Name of the company if the user did not change it.
std::string name
Name of the company if the user changed it.
Dimensions (a width and height) of a rectangle in 2D.
std::string name
Name of the file.
Definition saveload.h:432
void Set(const FiosItem &item)
Set the title of the file.
Deals with finding savegames.
Definition fios.h:78
DetailedFileType detailed
Detailed file type.
Definition fileio_type.h:65
bool UserIsAllowedToChangeNewGRFs() const
Returns true when the user has sufficient privileges to edit newgrfs on a running game.
LandscapeType landscape
the landscape we're currently in
GameCreationSettings game_creation
settings used during the creation of a game (map)
Container for loading in mode SL_LOAD_CHECK.
Definition fios.h:33
bool checkable
True if the savegame could be checked by SL_LOAD_CHECK. (Old savegames are not checkable....
Definition fios.h:34
bool HasNewGrfs()
Check whether the game uses any NewGrfs.
Definition fios.h:67
std::string error_msg
Data to pass to string parameters when displaying error.
Definition fios.h:36
TimerGameCalendar::Year starting_year
Starting date.
Definition fios.h:43
CompanyPropertiesMap companies
Company information.
Definition fios.h:45
StringID error
Error message from loading. INVALID_STRING_ID if no error.
Definition fios.h:35
Gamelog gamelog
Gamelog actions.
Definition fios.h:50
bool HasErrors()
Check whether loading the game resulted in errors.
Definition fios.h:58
void Clear()
Reset read data.
Definition fios_gui.cpp:49
GRFListCompatibility grf_compatibility
Summary state of NewGrfs, whether missing files or only compatible found.
Definition fios.h:48
LandscapeType landscape
Landscape type.
Definition fios.h:42
GRFConfigList grfconfig
NewGrf configuration from save.
Definition fios.h:47
Data stored about a string that can be modified in the GUI.
int ok_button
Widget button of parent window to simulate when pressing OK in OSK.
int cancel_button
Widget button of parent window to simulate when pressing CANCEL in OSK.
static const int ACTION_CLEAR
Clear editbox.
constexpr uint Vertical() const
Get total vertical padding of RectPadding.
Specification of a rectangle with absolute coordinates of all edges.
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
Rect WithHeight(int height, bool end=false) const
Copy Rect and set its height.
Rect WithY(int new_top, int new_bottom) const
Create a new Rect, replacing the top and bottom coordiates.
Rect Translate(int x, int y) const
Copy and translate Rect by x,y pixels.
uint step_height
Step-size of height resize changes.
Definition window_gui.h:213
void OnTimeout() override
Called when this window's timeout has been reached.
Definition fios_gui.cpp:821
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
Definition fios_gui.cpp:667
const FiosItem * highlighted
Item in fios_items highlighted by mouse pointer, or nullptr.
Definition fios_gui.cpp:333
QueryString filter_editbox
Filter editbox;.
Definition fios_gui.cpp:337
void GenerateFileName()
Generate a default save filename.
Definition fios_gui.cpp:372
StringFilter string_filter
Filter for available items.
Definition fios_gui.cpp:336
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition fios_gui.cpp:892
std::vector< FiosItem * > display_list
Filtered display list.
Definition fios_gui.cpp:338
void OnMouseOver(Point pt, WidgetID widget) override
The mouse is currently moving over the window or has just moved outside of the window.
Definition fios_gui.cpp:792
void Close(int data=0) override
Hide the window and all its child windows, and mark them for a later deletion.
Definition fios_gui.cpp:480
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 fios_gui.cpp:634
void OnResize() override
Called after the window got resized.
Definition fios_gui.cpp:853
SaveLoadOperation fop
Type of file to select.
Definition fios_gui.cpp:329
FileList fios_items
Item list.
Definition fios_gui.cpp:330
QueryString filename_editbox
Filename editbox.
Definition fios_gui.cpp:327
void OnPaint() override
The window must be repainted.
Definition fios_gui.cpp:656
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
Definition fios_gui.cpp:489
const FiosItem * selected
Selected item in fios_items, or nullptr.
Definition fios_gui.cpp:332
FiosItem o_dir
Original dir (home dir for this browser)
Definition fios_gui.cpp:331
EventState OnKeyPress(char32_t key, uint16_t keycode) override
A key has been pressed.
Definition fios_gui.cpp:811
void OnEditboxChanged(WidgetID wid) override
The text in an editbox has been edited.
Definition fios_gui.cpp:949
String filter and state.
bool IsEmpty() const
Check whether any filter words were entered.
void SetFilterTerm(std::string_view str)
Set the term to filter on.
void ResetState()
Reset the matching state to process a new item.
bool GetState() const
Get the matching state of the current item.
std::string_view GetText() const
Get the current text.
Definition textbuf.cpp:284
void Assign(std::string_view text)
Copy a string into the textbuffer.
Definition textbuf.cpp:420
High level window description.
Definition window_gui.h:168
Data structure for an opened window.
Definition window_gui.h:274
virtual void Close(int data=0)
Hide the window and all its child windows, and mark them for a later deletion.
Definition window.cpp:1104
static int SortButtonWidth()
Get width of up/down arrow of sort button state.
Definition widget.cpp:815
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition window.cpp:1809
std::map< WidgetID, QueryString * > querystrings
QueryString associated to WWT_EDITBOX widgets.
Definition window_gui.h:321
void DrawWidgets() const
Paint all widgets of a window.
Definition widget.cpp:766
void InvalidateData(int data=0, bool gui_scope=true)
Mark this window's data as invalid (in need of re-computing)
Definition window.cpp:3240
void SetWidgetDirty(WidgetID widget_index) const
Invalidate a widget, i.e.
Definition window.cpp:558
void DrawSortButtonState(WidgetID widget, SortButtonState state) const
Draw a sort button's up or down arrow symbol.
Definition widget.cpp:798
ResizeInfo resize
Resize information.
Definition window_gui.h:315
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
Definition window.cpp:1799
bool SetFocusedWidget(WidgetID widget_index)
Set focus within this window to the given widget.
Definition window.cpp:487
bool IsWidgetLowered(WidgetID widget_index) const
Gets the lowered state of a widget.
Definition window_gui.h:492
void LowerWidget(WidgetID widget_index)
Marks a widget as lowered.
Definition window_gui.h:461
void HandleButtonClick(WidgetID widget)
Do all things to make a button look clicked and mark it to be unclicked in a few ticks.
Definition window.cpp:597
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
Definition window.cpp:315
void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition window_gui.h:382
@ CONTENT_TYPE_SCENARIO
The content consists of a scenario.
@ CONTENT_TYPE_HEIGHTMAP
The content consists of a heightmap.
Functions related to tile highlights.
void ResetObjectToPlace()
Reset the cursor and mouse mode handling back to default (normal cursor, only clicking in windows).
void SetObjectToPlace(CursorID icon, PaletteID pal, HighLightStyle mode, WindowClass window_class, WindowNumber window_num)
Change the cursor and mouse click/drag handling to a mode for performing special operations like tile...
@ HT_NONE
default
Definition of the game-calendar-timer.
@ WWT_PUSHTXTBTN
Normal push-button (no toggle button) with text caption.
@ WWT_INSET
Pressed (inset) panel, most commonly used as combo box text area.
Definition widget_type.h:40
@ WWT_PUSHIMGBTN
Normal push-button (no toggle button) with image caption.
@ WWT_EDITBOX
a textbox for typing
Definition widget_type.h:62
@ NWID_HORIZONTAL
Horizontal container.
Definition widget_type.h:66
@ WWT_PANEL
Simple depressed panel.
Definition widget_type.h:39
@ WWT_CAPTION
Window caption (window title between closebox and stickybox)
Definition widget_type.h:52
@ NWID_VSCROLLBAR
Vertical scrollbar.
Definition widget_type.h:76
@ NWID_VERTICAL
Vertical container.
Definition widget_type.h:68
@ WWT_CLOSEBOX
Close box (at top-left of a window)
Definition widget_type.h:60
@ WWT_RESIZEBOX
Resize box (normally at bottom-right of a window)
Definition widget_type.h:59
@ WWT_DEFSIZEBOX
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX)
Definition widget_type.h:56
@ WWT_TEXT
Pure simple text.
Definition widget_type.h:49
@ NWID_SELECTION
Stacked widgets, only one visible at a time (eg in a panel with tabs).
Definition widget_type.h:71
@ SZSP_HORIZONTAL
Display plane with zero size vertically, and filling and resizing horizontally.
@ EqualSize
Containers should keep all their (resizing) children equally large.
void CloseWindowById(WindowClass cls, WindowNumber number, bool force, int data)
Close a window by its class and window number (if it is open).
Definition window.cpp:1195
Window functions not directly related to making/drawing windows.
@ SBS_DOWN
Sort ascending.
Definition window_gui.h:219
@ SBS_UP
Sort descending.
Definition window_gui.h:220
@ WDP_CENTER
Center the window.
Definition window_gui.h:145
int WidgetID
Widget ID.
Definition window_type.h:20
EventState
State of handling an event.
@ ES_HANDLED
The passed event is handled.
@ ES_NOT_HANDLED
The passed event is not handled.
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition window_type.h:50
@ WC_MAIN_WINDOW
Main window; Window numbers:
Definition window_type.h:56
@ WC_SAVELOAD
Saveload window; Window numbers: