OpenTTD Source 20260421-master-gc2fbc6fdeb
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
9
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
47enum class SavegameSorter : uint8_t {
50};
51
53static bool _savegame_sorter_ascending = false;
54
56bool FiosItemSorter(const FiosItem &a, const FiosItem &b)
57{
58 switch (_savegame_sorter) {
63 default:
64 NOT_REACHED();
65 }
66}
67
72{
73 this->checkable = false;
75 this->error_msg.clear();
76
77 this->map_size_x = this->map_size_y = 256; // Default for old savegames which do not store mapsize.
78 this->current_date = CalendarTime::MIN_DATE;
79 this->landscape = {};
80 this->starting_year = {};
81
82 companies.clear();
83
84 this->gamelog.Reset();
85
87}
88
90static constexpr std::initializer_list<NWidgetPart> _nested_load_dialog_widgets = {
96 /* Current directory and free space */
99
101 /* Left side : filter box and available files */
103 /* Filter box with label */
106 SetPIP(WidgetDimensions::unscaled.frametext.left, WidgetDimensions::unscaled.frametext.right, 0),
107 NWidget(WWT_TEXT, Colours::Invalid), SetFill(0, 1), SetStringTip(STR_SAVELOAD_FILTER_TITLE),
109 SetStringTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
110 EndContainer(),
111 EndContainer(),
112 /* Sort buttons */
115 NWidget(WWT_PUSHTXTBTN, Colours::Grey, WID_SL_SORT_BYNAME), SetStringTip(STR_SORT_BY_CAPTION_NAME, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
116 NWidget(WWT_PUSHTXTBTN, Colours::Grey, WID_SL_SORT_BYDATE), SetStringTip(STR_SORT_BY_CAPTION_DATE, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
117 EndContainer(),
118 NWidget(WWT_PUSHIMGBTN, Colours::Grey, WID_SL_HOME_BUTTON), SetAspect(1), SetSpriteTip(SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON_TOOLTIP),
119 EndContainer(),
120 /* Files */
124 SetToolTip(STR_SAVELOAD_LIST_TOOLTIP), SetResize(1, 10), SetScrollbar(WID_SL_SCROLLBAR),
125 EndContainer(),
126 EndContainer(),
128 EndContainer(),
129 /* Online Content button */
132 SetStringTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT),
133 EndContainer(),
134 EndContainer(),
135
136 /* Right side : game details */
139 EndContainer(),
140 NWidget(WWT_PUSHTXTBTN, Colours::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),
143 NWidget(WWT_PUSHTXTBTN, Colours::Grey, WID_SL_NEWGRF_INFO), SetStringTip(STR_MAPGEN_NEWGRF_SETTINGS, STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
144 NWidget(WWT_PUSHTXTBTN, Colours::Grey, WID_SL_LOAD_BUTTON), SetStringTip(STR_SAVELOAD_LOAD_BUTTON, STR_SAVELOAD_LOAD_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
145 EndContainer(),
147 EndContainer(),
148 EndContainer(),
149 EndContainer(),
150};
151
153static constexpr std::initializer_list<NWidgetPart> _nested_load_heightmap_dialog_widgets = {
158 EndContainer(),
159 /* Current directory and free space */
161 EndContainer(),
162
163 /* Filter box with label */
166 SetPIP(WidgetDimensions::unscaled.frametext.left, WidgetDimensions::unscaled.frametext.right, 0),
167 NWidget(WWT_TEXT, Colours::Invalid), SetFill(0, 1), SetStringTip(STR_SAVELOAD_FILTER_TITLE),
169 SetStringTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
170 EndContainer(),
171 EndContainer(),
172 /* Sort Buttons */
175 NWidget(WWT_PUSHTXTBTN, Colours::Grey, WID_SL_SORT_BYNAME), SetStringTip(STR_SORT_BY_CAPTION_NAME, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
176 NWidget(WWT_PUSHTXTBTN, Colours::Grey, WID_SL_SORT_BYDATE), SetStringTip(STR_SORT_BY_CAPTION_DATE, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
177 EndContainer(),
178 NWidget(WWT_PUSHIMGBTN, Colours::Grey, WID_SL_HOME_BUTTON), SetAspect(1), SetSpriteTip(SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON_TOOLTIP),
179 EndContainer(),
180 /* Files */
184 SetToolTip(STR_SAVELOAD_LIST_TOOLTIP), SetResize(1, 10), SetScrollbar(WID_SL_SCROLLBAR),
185 EndContainer(),
186 EndContainer(),
188 EndContainer(),
189 /* Online Content and Load button */
192 SetStringTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT),
194 SetStringTip(STR_SAVELOAD_LOAD_BUTTON, STR_SAVELOAD_LOAD_HEIGHTMAP_TOOLTIP),
196 EndContainer(),
197};
198
200static constexpr std::initializer_list<NWidgetPart> _nested_load_town_data_dialog_widgets = {
205 EndContainer(),
206 /* Current directory and free space */
208
209 /* Filter box with label */
212 SetPIP(WidgetDimensions::unscaled.frametext.left, WidgetDimensions::unscaled.frametext.right, 0),
213 NWidget(WWT_TEXT, Colours::Invalid), SetFill(0, 1), SetStringTip(STR_SAVELOAD_FILTER_TITLE),
214 NWidget(WWT_EDITBOX, Colours::Grey, WID_SL_FILTER), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
215 EndContainer(),
216 EndContainer(),
217 /* Sort Buttons */
220 NWidget(WWT_PUSHTXTBTN, Colours::Grey, WID_SL_SORT_BYNAME), SetStringTip(STR_SORT_BY_CAPTION_NAME, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
221 NWidget(WWT_PUSHTXTBTN, Colours::Grey, WID_SL_SORT_BYDATE), SetStringTip(STR_SORT_BY_CAPTION_DATE, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
222 EndContainer(),
223 NWidget(WWT_PUSHIMGBTN, Colours::Grey, WID_SL_HOME_BUTTON), SetAspect(1), SetSpriteTip(SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON_TOOLTIP),
224 EndContainer(),
225 /* Files */
229 SetToolTip(STR_SAVELOAD_LIST_TOOLTIP), SetResize(1, 10), SetScrollbar(WID_SL_SCROLLBAR), EndContainer(),
230 EndContainer(),
232 EndContainer(),
233 /* Load button */
236 SetStringTip(STR_SAVELOAD_LOAD_BUTTON, STR_SAVELOAD_LOAD_TOWN_DATA_TOOLTIP),
238 EndContainer(),
239};
240
242static constexpr std::initializer_list<NWidgetPart> _nested_save_dialog_widgets = {
247 EndContainer(),
248 /* Current directory and free space */
250 EndContainer(),
251
253 /* Left side : filter box and available files */
255 /* Filter box with label */
258 SetPIP(WidgetDimensions::unscaled.frametext.left, WidgetDimensions::unscaled.frametext.right, 0),
259 NWidget(WWT_TEXT, Colours::Invalid), SetFill(0, 1), SetStringTip(STR_SAVELOAD_FILTER_TITLE),
261 SetStringTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
262 EndContainer(),
263 EndContainer(),
264 /* Sort buttons */
267 NWidget(WWT_PUSHTXTBTN, Colours::Grey, WID_SL_SORT_BYNAME), SetStringTip(STR_SORT_BY_CAPTION_NAME, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
268 NWidget(WWT_PUSHTXTBTN, Colours::Grey, WID_SL_SORT_BYDATE), SetStringTip(STR_SORT_BY_CAPTION_DATE, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
269 EndContainer(),
270 NWidget(WWT_PUSHIMGBTN, Colours::Grey, WID_SL_HOME_BUTTON), SetAspect(1), SetSpriteTip(SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON_TOOLTIP),
271 EndContainer(),
272 /* Files */
276 SetToolTip(STR_SAVELOAD_LIST_TOOLTIP), SetResize(1, 10), SetScrollbar(WID_SL_SCROLLBAR),
277 EndContainer(),
278 EndContainer(),
280 EndContainer(),
283 SetStringTip(STR_SAVELOAD_OSKTITLE, STR_SAVELOAD_EDITBOX_TOOLTIP),
284 EndContainer(),
285 /* Save/delete buttons */
287 NWidget(WWT_PUSHTXTBTN, Colours::Grey, WID_SL_DELETE_SELECTION), SetStringTip(STR_SAVELOAD_DELETE_BUTTON, STR_SAVELOAD_DELETE_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
288 NWidget(WWT_PUSHTXTBTN, Colours::Grey, WID_SL_SAVE_GAME), SetStringTip(STR_SAVELOAD_SAVE_BUTTON, STR_SAVELOAD_SAVE_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
289 EndContainer(),
290 EndContainer(),
291
292 /* Right side : game details */
295 EndContainer(),
298 EndContainer(),
300 EndContainer(),
301 EndContainer(),
302 EndContainer(),
303};
304
307 TC_LIGHT_BROWN, // DetailedFileType::OldGameFile
308 TC_ORANGE, // DetailedFileType::GameFile
309 TC_YELLOW, // DetailedFileType::HeightmapBmp
310 TC_ORANGE, // DetailedFileType::HeightmapPng
311 TC_LIGHT_BROWN, // DetailedFileType::TownDataJson
312 TC_LIGHT_BLUE, // DetailedFileType::FiosDrive
313 TC_DARK_GREEN, // DetailedFileType::FiosParent
314 TC_DARK_GREEN, // DetailedFileType::FiosDirectory
315 TC_ORANGE, // DetailedFileType::FiosDirect
316};
317
322static void SortSaveGameList(FileList &file_list)
323{
324 size_t sort_start = 0;
325 size_t sort_end = 0;
326
327 /* Directories are always above the files (FIOS_TYPE_DIR)
328 * Drives (A:\ (windows only) are always under the files (FIOS_TYPE_DRIVE)
329 * Only sort savegames/scenarios, not directories
330 */
331 for (const auto &item : file_list) {
332 switch (item.type.detailed) {
333 case DetailedFileType::FiosDirectory: sort_start++; break;
334 case DetailedFileType::FiosParent: sort_start++; break;
335 case DetailedFileType::FiosDrive: sort_end++; break;
336 default: break;
337 }
338 }
339
340 std::sort(file_list.begin() + sort_start, file_list.end() - sort_end, FiosItemSorter);
341}
342
343struct SaveLoadWindow : public Window {
344private:
345 static const uint EDITBOX_MAX_SIZE = 50;
346
352 const FiosItem *selected = nullptr;
353 const FiosItem *highlighted = nullptr;
354 Scrollbar *vscroll = nullptr;
355
358 std::vector<FiosItem *> display_list{};
359
360 static void SaveGameConfirmationCallback(Window *, bool confirmed)
361 {
362 /* File name has already been written to _file_to_saveload */
363 if (confirmed) _switch_mode = SM_SAVE_GAME;
364 }
365
366 static void SaveHeightmapConfirmationCallback(Window *, bool confirmed)
367 {
368 /* File name has already been written to _file_to_saveload */
369 if (confirmed) _switch_mode = SM_SAVE_HEIGHTMAP;
370 }
371
372 static void DeleteFileConfirmationCallback(Window *window, bool confirmed)
373 {
374 auto *save_load_window = static_cast<SaveLoadWindow*>(window);
375
376 assert(save_load_window->selected != nullptr);
377
378 if (confirmed) {
379 if (!FioRemove(save_load_window->selected->name)) {
380 ShowErrorMessage(GetEncodedString(STR_ERROR_UNABLE_TO_DELETE_FILE), {}, WL_ERROR);
381 } else {
382 save_load_window->InvalidateData(SLIWD_RESCAN_FILES);
383 /* Reset file name to current date on successful delete */
384 if (save_load_window->abstract_filetype == AbstractFileType::Savegame) save_load_window->GenerateFileName();
385 }
386 }
387 }
388
389public:
390
393 {
394 this->filename_editbox.text.Assign(GenerateDefaultSaveName());
395 }
396
399 {
400 assert(this->fop == SaveLoadOperation::Save || this->fop == SaveLoadOperation::Load);
401
402 /* For saving, construct an initial file name. */
403 if (this->fop == SaveLoadOperation::Save) {
404 switch (this->abstract_filetype) {
406 this->GenerateFileName();
407 break;
408
411 this->filename_editbox.text.Assign("UNNAMED");
412 break;
413
414 default:
415 /* It's not currently possible to save town data. */
416 NOT_REACHED();
417 }
418 }
420 this->filename_editbox.ok_button = WID_SL_SAVE_GAME;
421
422 this->CreateNestedTree();
425 }
426
427 /* Select caption string of the window. */
428 StringID caption_string;
429 switch (this->abstract_filetype) {
431 caption_string = (this->fop == SaveLoadOperation::Save) ? STR_SAVELOAD_SAVE_CAPTION : STR_SAVELOAD_LOAD_CAPTION;
432 break;
433
435 caption_string = (this->fop == SaveLoadOperation::Save) ? STR_SAVELOAD_SAVE_SCENARIO : STR_SAVELOAD_LOAD_SCENARIO;
436 break;
437
439 caption_string = (this->fop == SaveLoadOperation::Save) ? STR_SAVELOAD_SAVE_HEIGHTMAP : STR_SAVELOAD_LOAD_HEIGHTMAP;
440 break;
441
443 caption_string = STR_SAVELOAD_LOAD_TOWN_DATA; // It's not currently possible to save town data.
444 break;
445
446 default:
447 NOT_REACHED();
448 }
449 this->GetWidget<NWidgetCore>(WID_SL_CAPTION)->SetString(caption_string);
450
451 this->vscroll = this->GetScrollbar(WID_SL_SCROLLBAR);
452 this->FinishInitNested(0);
453
456 this->filter_editbox.cancel_button = QueryString::ACTION_CLEAR;
457
458 /* pause is only used in single-player, non-editor mode, non-menu mode. It
459 * will be unpaused in the WE_DESTROY event handler. */
460 if (_game_mode != GM_MENU && !_networking && _game_mode != GM_EDITOR) {
461 Command<Commands::Pause>::Post(PauseMode::SaveLoad, true);
462 }
463 SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0);
464
466
468
469 /* Select the initial directory. */
470 o_dir.type = FIOS_TYPE_DIRECT;
471 switch (this->abstract_filetype) {
473 o_dir.name = FioFindDirectory(Subdirectory::Save);
474 break;
475
477 o_dir.name = FioFindDirectory(Subdirectory::Scenario);
478 break;
479
482 o_dir.name = FioFindDirectory(Subdirectory::Heightmap);
483 break;
484
485 default:
486 o_dir.name = _personal_dir;
487 }
488
489 switch (this->fop) {
491 /* Focus the edit box by default in the save window */
493 break;
494
495 default:
497 }
498 }
499
500 void Close([[maybe_unused]] int data = 0) override
501 {
502 /* pause is only used in single-player, non-editor mode, non menu mode */
503 if (!_networking && _game_mode != GM_EDITOR && _game_mode != GM_MENU) {
504 Command<Commands::Pause>::Post(PauseMode::SaveLoad, false);
505 }
506 this->Window::Close();
507 }
508
509 void DrawWidget(const Rect &r, WidgetID widget) const override
510 {
511 switch (widget) {
516 }
517 break;
518
519 case WID_SL_BACKGROUND: {
520 static std::string path;
521 static std::optional<uint64_t> free_space = std::nullopt;
522
523 if (_fios_path_changed) {
524 path = FiosGetCurrentPath();
525 free_space = FiosGetDiskFreeSpace(path);
526 _fios_path_changed = false;
527 }
528
529 Rect ir = r.Shrink(WidgetDimensions::scaled.framerect);
530
531 if (free_space.has_value()) {
532 DrawString(ir.left, ir.right, ir.top + GetCharacterHeight(FontSize::Normal), GetString(STR_SAVELOAD_BYTES_FREE, free_space.value()));
533 } else {
534 DrawString(ir.left, ir.right, ir.top + GetCharacterHeight(FontSize::Normal), STR_ERROR_UNABLE_TO_READ_DRIVE);
535 }
536 DrawString(ir.left, ir.right, ir.top, path, TC_BLACK);
537 break;
538 }
539
541 const Rect br = r.Shrink(WidgetDimensions::scaled.bevel);
543
544 Rect tr = r.Shrink(WidgetDimensions::scaled.inset).WithHeight(this->resize.step_height);
545 auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->display_list);
546 for (auto it = first; it != last; ++it) {
547 const FiosItem *item = *it;
548
549 if (item == this->selected) {
551 } else if (item == this->highlighted) {
553 }
554 DrawString(tr, item->title.GetDecodedString(), _fios_colours[item->type.detailed]);
555 tr = tr.Translate(0, this->resize.step_height);
556 }
557 break;
558 }
559
560 case WID_SL_DETAILS:
561 this->DrawDetails(r);
562 break;
563 }
564 }
565
566 void DrawDetails(const Rect &r) const
567 {
568 /* Header panel */
569 int HEADER_HEIGHT = GetCharacterHeight(FontSize::Normal) + WidgetDimensions::scaled.frametext.Vertical();
570
571 Rect hr = r.WithHeight(HEADER_HEIGHT).Shrink(WidgetDimensions::scaled.frametext);
572 Rect tr = r.Shrink(WidgetDimensions::scaled.frametext);
573 tr.top += HEADER_HEIGHT;
574
575 /* Create the nice lighter rectangle at the details top */
576 GfxFillRect(r.WithHeight(HEADER_HEIGHT).Shrink(WidgetDimensions::scaled.bevel.left, WidgetDimensions::scaled.bevel.top, WidgetDimensions::scaled.bevel.right, 0), GetColourGradient(Colours::Grey, SHADE_LIGHTEST));
577 DrawString(hr.left, hr.right, hr.top, STR_SAVELOAD_DETAIL_CAPTION, TC_FROMSTRING, SA_HOR_CENTER);
578
579 if (this->selected == nullptr) return;
580
581 /* Details panel */
582 tr.bottom -= GetCharacterHeight(FontSize::Normal) - 1;
583 if (tr.top > tr.bottom) return;
584
585 if (!_load_check_data.checkable) {
586 /* Old savegame, no information available */
587 DrawString(tr, STR_SAVELOAD_DETAIL_NOT_AVAILABLE);
590 /* Incompatible / broken savegame */
592 } else {
593 /* Mapsize */
594 DrawString(tr, GetString(STR_NETWORK_SERVER_LIST_MAP_SIZE, _load_check_data.map_size_x, _load_check_data.map_size_y));
596 if (tr.top > tr.bottom) return;
597
598 /* Climate */
599 if (to_underlying(_load_check_data.landscape) < NUM_LANDSCAPE) {
600 DrawString(tr, GetString(STR_NETWORK_SERVER_LIST_LANDSCAPE, STR_CLIMATE_TEMPERATE_LANDSCAPE + to_underlying(_load_check_data.landscape)));
602 }
603
605 if (tr.top > tr.bottom) return;
606
607 /* Start date (if available) */
609 DrawString(tr, GetString(STR_NETWORK_SERVER_LIST_START_DATE, TimerGameCalendar::ConvertYMDToDate(_load_check_data.starting_year, 0, 1)));
611 }
612 if (tr.top > tr.bottom) return;
613
614 /* Hide current date for scenarios */
616 /* Current date */
617 DrawString(tr, GetString(STR_NETWORK_SERVER_LIST_CURRENT_DATE, _load_check_data.current_date));
619 }
620
621 /* Hide the NewGRF stuff when saving. We also hide the button. */
624 if (tr.top > tr.bottom) return;
625
626 /* NewGrf compatibility */
627 DrawString(tr, GetString(STR_SAVELOAD_DETAIL_GRFSTATUS, _load_check_data.grfconfig.empty() ? STR_NEWGRF_LIST_NONE : STR_NEWGRF_LIST_ALL_FOUND + to_underlying(_load_check_data.grf_compatibility)));
629 }
630 if (tr.top > tr.bottom) return;
631
632 /* Hide the company stuff for scenarios */
635 if (tr.top > tr.bottom) return;
636
637 /* Companies / AIs */
638 for (auto &pair : _load_check_data.companies) {
639 const CompanyProperties &c = *pair.second;
640 if (c.name.empty()) {
641 AutoRestoreBackup landscape_backup(_settings_game.game_creation.landscape, _load_check_data.landscape);
642 DrawString(tr, GetString(STR_SAVELOAD_DETAIL_COMPANY_INDEX, pair.first + 1, c.name_1, c.name_2));
643 } else {
644 DrawString(tr, GetString(STR_SAVELOAD_DETAIL_COMPANY_INDEX, pair.first + 1, STR_JUST_RAW_STRING, c.name));
645 }
646
648 if (tr.top > tr.bottom) break;
649 }
650 }
651 }
652 }
653
654 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
655 {
656 switch (widget) {
658 size.height = 2 * GetCharacterHeight(FontSize::Normal) + padding.height;
659 break;
660
662 fill.height = resize.height = GetCharacterHeight(FontSize::Normal);
663 size.height = resize.height * 10 + padding.height;
664 break;
666 case WID_SL_SORT_BYDATE: {
668 d.width += padding.width + Window::SortButtonWidth() * 2; // Doubled since the string is centred and it also looks better.
669 d.height += padding.height;
670 size = maxdim(size, d);
671 break;
672 }
673 }
674 }
675
676 void OnPaint() override
677 {
678 if (_savegame_sort_dirty) {
679 _savegame_sort_dirty = false;
680 SortSaveGameList(this->fios_items);
682 }
683
684 this->DrawWidgets();
685 }
686
687 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
688 {
689 switch (widget) {
690 case WID_SL_SORT_BYNAME: // Sort save games by name
693 _savegame_sort_dirty = true;
694 this->SetDirty();
695 break;
696
697 case WID_SL_SORT_BYDATE: // Sort save games by date
700 _savegame_sort_dirty = true;
701 this->SetDirty();
702 break;
703
704 case WID_SL_HOME_BUTTON: // OpenTTD 'button', jumps to OpenTTD directory
707 break;
708
709 case WID_SL_LOAD_BUTTON: {
710 if (this->selected == nullptr || _load_check_data.HasErrors()) break;
711
712 _file_to_saveload.Set(*this->selected);
713
714 if (this->abstract_filetype == AbstractFileType::Heightmap) {
715 this->Close();
717 } else if (this->abstract_filetype == AbstractFileType::TownData) {
718 this->Close();
719 LoadTownData();
720 } else if (!_load_check_data.HasNewGrfs() || _load_check_data.grf_compatibility != GRFListCompatibility::NotFound || _settings_client.gui.UserIsAllowedToChangeNewGRFs()) {
721 _switch_mode = (_game_mode == GM_EDITOR) ? SM_LOAD_SCENARIO : SM_LOAD_GAME;
723 this->Close();
724 }
725 break;
726 }
727
729 if (_load_check_data.HasNewGrfs()) {
730 ShowNewGRFSettings(false, false, false, _load_check_data.grfconfig);
731 }
732 break;
733
735 if (!_network_available) {
736 ShowErrorMessage(GetEncodedString(STR_NETWORK_ERROR_NOTAVAILABLE), {}, WL_ERROR);
737 } else if (_load_check_data.HasNewGrfs()) {
739 }
740 break;
741
742 case WID_SL_DRIVES_DIRECTORIES_LIST: { // Click the listbox
743 auto it = this->vscroll->GetScrolledItemFromWidget(this->display_list, pt.y, this, WID_SL_DRIVES_DIRECTORIES_LIST, WidgetDimensions::scaled.inset.top);
744 if (it == this->display_list.end()) return;
745
746 /* Get the corresponding non-filtered out item from the list */
747 const FiosItem *file = *it;
748
749 if (FiosBrowseTo(file)) {
750 /* Changed directory, need refresh. */
752 break;
753 }
754
755 if (click_count == 1) {
756 if (this->selected != file) {
757 this->selected = file;
758 _load_check_data.Clear();
759
760 if (file->type.detailed == DetailedFileType::GameFile) {
761 /* Other detailed file types cannot be checked before. */
763 }
764
766 }
767 if (this->fop == SaveLoadOperation::Save) {
768 /* Copy clicked name to editbox */
769 this->filename_editbox.text.Assign(file->title.GetDecodedString());
771 }
772 } else if (!_load_check_data.HasErrors()) {
773 this->selected = file;
774 if (this->fop == SaveLoadOperation::Load) {
775 if (this->abstract_filetype == AbstractFileType::Savegame || this->abstract_filetype == AbstractFileType::Scenario || this->abstract_filetype == AbstractFileType::TownData) {
776 this->OnClick(pt, WID_SL_LOAD_BUTTON, 1);
777 } else {
778 assert(this->abstract_filetype == AbstractFileType::Heightmap);
779 _file_to_saveload.Set(*file);
780
781 this->Close();
783 }
784 }
785 }
786 break;
787 }
788
790 if (!_network_available) {
791 ShowErrorMessage(GetEncodedString(STR_NETWORK_ERROR_NOTAVAILABLE), {}, WL_ERROR);
792 } else {
793 assert(this->fop == SaveLoadOperation::Load);
794 switch (this->abstract_filetype) {
795 default: NOT_REACHED();
798 }
799 }
800 break;
801
802 case WID_SL_DELETE_SELECTION: // Delete
803 break;
804
805 case WID_SL_SAVE_GAME: // Save game
806 /* Note, this is also called via the OSK; and we need to lower the button. */
808 break;
809 }
810 }
811
812 void OnMouseOver([[maybe_unused]] Point pt, WidgetID widget) override
813 {
814 if (widget == WID_SL_DRIVES_DIRECTORIES_LIST) {
815 auto it = this->vscroll->GetScrolledItemFromWidget(this->display_list, pt.y, this, WID_SL_DRIVES_DIRECTORIES_LIST, WidgetDimensions::scaled.inset.top);
816 if (it == this->display_list.end()) return;
817
818 /* Get the corresponding non-filtered out item from the list */
819 const FiosItem *file = *it;
820
821 if (file != this->highlighted) {
822 this->highlighted = file;
824 }
825 } else if (this->highlighted != nullptr) {
826 this->highlighted = nullptr;
828 }
829 }
830
831 EventState OnKeyPress([[maybe_unused]] char32_t key, uint16_t keycode) override
832 {
833 if (keycode == WKC_ESC) {
834 this->Close();
835 return ES_HANDLED;
836 }
837
838 return ES_NOT_HANDLED;
839 }
840
841 void OnTimeout() override
842 {
843 /* Widgets WID_SL_DELETE_SELECTION and WID_SL_SAVE_GAME only exist when saving to a file. */
844 if (this->fop != SaveLoadOperation::Save) return;
845
846 if (this->IsWidgetLowered(WID_SL_DELETE_SELECTION)) { // Delete button clicked
847 ShowQuery(GetEncodedString(STR_SAVELOAD_DELETE_TITLE), GetEncodedString(STR_SAVELOAD_DELETE_WARNING),
848 this, SaveLoadWindow::DeleteFileConfirmationCallback);
849 } else if (this->IsWidgetLowered(WID_SL_SAVE_GAME)) { // Save button clicked
850 if (this->abstract_filetype == AbstractFileType::Savegame || this->abstract_filetype == AbstractFileType::Scenario) {
851 _file_to_saveload.name = FiosMakeSavegameName(this->filename_editbox.text.GetText());
853 ShowQuery(GetEncodedString(STR_SAVELOAD_OVERWRITE_TITLE), GetEncodedString(STR_SAVELOAD_OVERWRITE_WARNING),
854 this, SaveLoadWindow::SaveGameConfirmationCallback);
855 } else {
857 }
858 } else {
859 _file_to_saveload.name = FiosMakeHeightmapName(this->filename_editbox.text.GetText());
861 ShowQuery(GetEncodedString(STR_SAVELOAD_OVERWRITE_TITLE), GetEncodedString(STR_SAVELOAD_OVERWRITE_WARNING),
862 this, SaveLoadWindow::SaveHeightmapConfirmationCallback);
863 } else {
865 }
866 }
867
868 /* In the editor set up the vehicle engines correctly (date might have changed) */
869 if (_game_mode == GM_EDITOR) StartupEngines();
870 }
871 }
872
873 void OnResize() override
874 {
876 }
877
878 void BuildDisplayList()
879 {
880 /* Filter changes */
881 this->display_list.clear();
882 this->display_list.reserve(this->fios_items.size());
883
884 if (this->string_filter.IsEmpty()) {
885 /* We don't filter anything out if the filter editbox is empty */
886 for (auto &it : this->fios_items) {
887 this->display_list.push_back(&it);
888 }
889 } else {
890 for (auto &it : this->fios_items) {
891 this->string_filter.ResetState();
892 this->string_filter.AddLine(it.title.GetDecodedString());
893 /* We set the vector to show this fios element as filtered depending on the result of the filter */
894 if (this->string_filter.GetState()) {
895 this->display_list.push_back(&it);
896 } else if (&it == this->selected) {
897 /* The selected element has been filtered out */
898 this->selected = nullptr;
900 }
901 }
902 }
903
904 this->vscroll->SetCount(this->display_list.size());
905 }
906
912 void OnInvalidateData(int data = 0, bool gui_scope = true) override
913 {
914 switch (data) {
916 /* Rescan files */
917 this->selected = nullptr;
918 _load_check_data.Clear();
919 if (!gui_scope) break;
920
921 _fios_path_changed = true;
922 this->fios_items.BuildFileList(this->abstract_filetype, this->fop, true);
923 this->selected = nullptr;
924 _load_check_data.Clear();
925
926 /* We reset the files filtered */
928
929 [[fallthrough]];
930
932 /* Selection changes */
933 if (!gui_scope) break;
934
935 if (this->fop == SaveLoadOperation::Save) this->SetWidgetDisabledState(WID_SL_DELETE_SELECTION, this->selected == nullptr);
936
937 if (this->fop != SaveLoadOperation::Load) break;
938
939 switch (this->abstract_filetype) {
942 this->SetWidgetDisabledState(WID_SL_LOAD_BUTTON, this->selected == nullptr || _load_check_data.HasErrors());
943 break;
944
947 bool disabled = this->selected == nullptr || _load_check_data.HasErrors();
948 if (!_settings_client.gui.UserIsAllowedToChangeNewGRFs()) {
949 disabled |= _load_check_data.HasNewGrfs() && _load_check_data.grf_compatibility == GRFListCompatibility::NotFound;
950 }
954 !_load_check_data.HasNewGrfs() || _load_check_data.grf_compatibility == GRFListCompatibility::AllGood);
955 break;
956 }
957
958 default:
959 NOT_REACHED();
960 }
961 break;
962
964 this->BuildDisplayList();
965 break;
966 }
967 }
968
969 void OnEditboxChanged(WidgetID wid) override
970 {
971 if (wid == WID_SL_FILTER) {
972 this->string_filter.SetFilterTerm(this->filter_editbox.text.GetText());
974 }
975
976 if (wid == WID_SL_SAVE_OSK_TITLE) {
977 this->selected = nullptr;
979 }
980 }
981};
982
985 WDP_CENTER, "load_game", 500, 294,
987 {},
989);
990
993 WDP_CENTER, "load_heightmap", 257, 320,
995 {},
997);
998
1001 WDP_CENTER, "load_town_data", 257, 320,
1003 {},
1005);
1006
1009 WDP_CENTER, "save_game", 500, 294,
1011 {},
1013);
1014
1021{
1023
1024 if (fop == SaveLoadOperation::Save) {
1025 new SaveLoadWindow(_save_dialog_desc, abstract_filetype, fop);
1026 } else {
1027 /* Dialogue for loading a file. */
1028 switch (abstract_filetype) {
1030 new SaveLoadWindow(_load_heightmap_dialog_desc, abstract_filetype, fop);
1031 break;
1032
1034 new SaveLoadWindow(_load_town_data_dialog_desc, abstract_filetype, fop);
1035 break;
1036
1037 default:
1038 new SaveLoadWindow(_load_dialog_desc, abstract_filetype, fop);
1039 }
1040 }
1041}
std::string GetDecodedString() const
Decode the encoded string.
Definition strings.cpp:207
A sort-of mixin that implements 'at(pos)' and 'operator[](pos)' only for a specific enum class.
List of file information.
Definition fios.h:86
Scrollbar data structure.
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:2532
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
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
static const WidgetDimensions unscaled
Unscaled widget dimensions.
Definition window_gui.h:93
Functions related to commands.
void StartupEngines()
Start/initialise all our engines.
Definition engine.cpp:804
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:21
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:331
std::string _personal_dir
custom directory for personal settings, saves, newgrf, etc.
Definition fileio.cpp:877
bool FioCheckFileExists(std::string_view filename, Subdirectory subdir)
Check whether the given file exists.
Definition fileio.cpp:123
Functions for standard in/out file operations.
SaveLoadOperation
Operation performed on the file.
Definition fileio_type.h:52
@ Check
Load file for checking and/or preview.
Definition fileio_type.h:53
@ Save
File is being saved.
Definition fileio_type.h:55
@ Load
File is being loaded.
Definition fileio_type.h:54
DetailedFileType
Kinds of files in each AbstractFileType.
Definition fileio_type.h:28
@ FiosDrive
A drive (letter) entry.
Definition fileio_type.h:41
@ GameFile
Save game or scenario file.
Definition fileio_type.h:31
@ End
End marker.
Definition fileio_type.h:46
@ FiosDirectory
A directory entry.
Definition fileio_type.h:43
@ FiosParent
A parent directory entry.
Definition fileio_type.h:42
@ Scenario
Base directory for all scenarios.
Definition fileio_type.h:92
@ Heightmap
Subdirectory of scenario for heightmaps.
Definition fileio_type.h:93
@ None
A path without any base directory.
@ Save
Base directory for all savegames.
Definition fileio_type.h:90
AbstractFileType
The different abstract types of files that the system knows about.
Definition fileio_type.h:17
@ Savegame
old or new savegame
Definition fileio_type.h:19
@ Scenario
old or new scenario
Definition fileio_type.h:20
@ Heightmap
heightmap file
Definition fileio_type.h:21
@ TownData
town data file
Definition fileio_type.h:22
bool FiosItemModificationDateSorter(const FiosItem &a, const FiosItem &b)
Sort files by their modification date, and name when they are equal.
Definition fios.cpp:45
std::string FiosMakeSavegameName(std::string_view name)
Make a save game or scenario filename from a name.
Definition fios.cpp:207
bool FiosItemNameSorter(const FiosItem &a, const FiosItem &b)
Sort files by their name.
Definition fios.cpp:39
std::string FiosGetCurrentPath()
Get the current path/working directory.
Definition fios.cpp:123
std::string FiosMakeHeightmapName(std::string_view name)
Construct a filename for a height map.
Definition fios.cpp:219
bool FiosBrowseTo(const FiosItem *item)
Browse to a new path based on the passed item, starting at _fios_path.
Definition fios.cpp:133
Declarations for savegames operations.
bool FiosItemSorter(const FiosItem &a, const FiosItem &b)
Sorts the FiosItems based on the savegame sorter and order.
Definition fios_gui.cpp:56
@ 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
LoadCheckData _load_check_data
Data loaded from save during SL_LOAD_CHECK.
Definition fios_gui.cpp:41
bool FiosItemSorter(const FiosItem &a, const FiosItem &b)
Sorts the FiosItems based on the savegame sorter and order.
Definition fios_gui.cpp:56
static SavegameSorter _savegame_sorter
Sorter for savegames.
Definition fios_gui.cpp:52
static bool _savegame_sorter_ascending
Sorter for savegames.
Definition fios_gui.cpp:53
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:242
static constexpr std::initializer_list< NWidgetPart > _nested_load_heightmap_dialog_widgets
Load heightmap with content download.
Definition fios_gui.cpp:153
static constexpr std::initializer_list< NWidgetPart > _nested_load_dialog_widgets
Load game/scenario with optional content download.
Definition fios_gui.cpp:90
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:200
LoadCheckData _load_check_data
Data loaded from save during SL_LOAD_CHECK.
Definition fios_gui.cpp:41
SavegameSorter
The available sorters for FiosItems.
Definition fios_gui.cpp:47
@ Date
Sort by date.
Definition fios_gui.cpp:48
@ Name
Sort by name.
Definition fios_gui.cpp:49
static const EnumClassIndexContainer< std::array< TextColour, to_underlying(DetailedFileType::End)>, DetailedFileType > _fios_colours
Text colours of DetailedFileType fios entries in the window.
Definition fios_gui.cpp:306
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:322
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:88
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:900
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:669
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:788
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:116
SwitchMode _switch_mode
The next mainloop command.
Definition gfx.cpp:50
Functions related to the gfx engine.
@ 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
@ Invalid
Invalid marker.
Definition gfx_type.h:302
@ Grey
Grey.
Definition gfx_type.h:299
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:980
GUI functions that shouldn't be here.
Types related to the landscape.
#define Rect
Macro that prevents name conflicts between included headers.
#define Point
Macro that prevents name conflicts between included headers.
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:69
bool _networking
are we in networking mode?
Definition network.cpp:67
Basic functions/variables used all over the place.
Part of the network protocol handling content distribution.
void ShowNetworkContentListWindow(ContentVector *cv=nullptr, ContentType type1=ContentType::End, ContentType type2=ContentType::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.
@ NotFound
At least one GRF couldn't be found (higher priority than GRFListCompatibility::Compatible).
@ AllGood
All GRF needed by game are present.
void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfigList &config)
Setup the NewGRF gui.
@ SaveLoad
A game paused for saving/loading.
Definition openttd.h:70
@ 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:393
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).
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.
Deals with finding savegames.
Definition fios.h:78
DetailedFileType detailed
Detailed file type.
Definition fileio_type.h:65
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
void Clear()
Reset read data.
Definition fios_gui.cpp:71
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.
static const int ACTION_CLEAR
Clear editbox.
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.
void OnTimeout() override
Called when this window's timeout has been reached.
Definition fios_gui.cpp:841
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:687
const FiosItem * highlighted
Item in fios_items highlighted by mouse pointer, or nullptr.
Definition fios_gui.cpp:353
QueryString filter_editbox
Filter editbox;.
Definition fios_gui.cpp:357
void GenerateFileName()
Generate a default save filename.
Definition fios_gui.cpp:392
StringFilter string_filter
Filter for available items.
Definition fios_gui.cpp:356
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition fios_gui.cpp:912
std::vector< FiosItem * > display_list
Filtered display list.
Definition fios_gui.cpp:358
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:812
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:500
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:654
void OnResize() override
Called after the window got resized.
Definition fios_gui.cpp:873
SaveLoadOperation fop
File operation to perform.
Definition fios_gui.cpp:349
FileList fios_items
Item list.
Definition fios_gui.cpp:350
QueryString filename_editbox
Filename editbox.
Definition fios_gui.cpp:347
void OnPaint() override
The window must be repainted.
Definition fios_gui.cpp:676
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
Definition fios_gui.cpp:509
AbstractFileType abstract_filetype
Type of file to select.
Definition fios_gui.cpp:348
const FiosItem * selected
Selected item in fios_items, or nullptr.
Definition fios_gui.cpp:352
FiosItem o_dir
Original dir (home dir for this browser).
Definition fios_gui.cpp:351
EventState OnKeyPress(char32_t key, uint16_t keycode) override
A key has been pressed.
Definition fios_gui.cpp:831
void OnEditboxChanged(WidgetID wid) override
The text in an editbox has been edited.
Definition fios_gui.cpp:969
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.
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:1117
static int SortButtonWidth()
Get width of up/down arrow of sort button state.
Definition widget.cpp:835
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition window.cpp:1822
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:786
void InvalidateData(int data=0, bool gui_scope=true)
Mark this window's data as invalid (in need of re-computing).
Definition window.cpp:3262
void SetWidgetDirty(WidgetID widget_index) const
Invalidate a widget, i.e.
Definition window.cpp:570
void DrawSortButtonState(WidgetID widget, SortButtonState state) const
Draw a sort button's up or down arrow symbol.
Definition widget.cpp:818
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:1812
bool SetFocusedWidget(WidgetID widget_index)
Set focus within this window to the given widget.
Definition window.cpp:499
bool IsWidgetLowered(WidgetID widget_index) const
Gets the lowered state of a widget.
Definition window_gui.h:492
Window(WindowDesc &desc)
Empty constructor, initialization has been moved to InitNested() called from the constructor of the d...
Definition window.cpp:1846
const NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
Definition window_gui.h:990
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:609
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
Definition window.cpp:327
void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition window_gui.h:382
@ Scenario
The content consists of a scenario.
@ 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:1209
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:21
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:51
@ WC_MAIN_WINDOW
Main window; Window numbers:
Definition window_type.h:57
@ WC_SAVELOAD
Saveload window; Window numbers: