OpenTTD Source: src/help_gui.cpp Source File

OpenTTD Source 15.0-beta1

help_gui.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10#include "stdafx.h"
11#include "gui.h"
12#include "window_gui.h"
13#include "textfile_gui.h"
14#include "fileio_func.h"
15#include "table/control_codes.h"
16#include "string_func.h"
17#include "openttd.h"
18#include "help_gui.h"
19
20#include "widgets/help_widget.h"
21#include "widgets/misc_widget.h"
22
23#include "safeguards.h"
24
25static const std::string README_FILENAME = "README.md";
26static const std::string CHANGELOG_FILENAME = "changelog.md";
27static const std::string KNOWN_BUGS_FILENAME = "known-bugs.md";
28static const std::string LICENSE_FILENAME = "COPYING.md";
29
30static const std::string WEBSITE_LINK = "https://www.openttd.org/";
31static const std::string WIKI_LINK = "https://wiki.openttd.org/";
32static const std::string BUGTRACKER_LINK = "https://bugs.openttd.org/";
33static const std::string COMMUNITY_LINK = "https://community.openttd.org/";
34
36 static constexpr size_t CHANGELOG_VERSIONS_LIMIT = 20;
37
44 static std::optional<std::string> FindGameManualFilePath(std::string_view filename)
45{
46 static const Searchpath searchpaths[] = {
47 SP_APPLICATION_BUNDLE_DIR, SP_INSTALLATION_DIR, SP_SHARED_DIR, SP_BINARY_DIR, SP_WORKING_DIR
48 };
49
50 for (Searchpath sp : searchpaths) {
51 auto file_path = FioGetDirectory(sp, BASE_DIR) + filename.data();
52 if (FioCheckFileExists(file_path, NO_DIRECTORY)) return file_path;
53 }
54
55 return {};
56}
57
59 struct GameManualTextfileWindow : public TextfileWindow {
60 GameManualTextfileWindow(std::string_view filename) : TextfileWindow(TFT_GAME_MANUAL)
61 {
62 this->ConstructWindow();
63
64 /* Mark the content of these files as trusted. */
65 this->trusted = true;
66
67 auto filepath = FindGameManualFilePath(filename);
68 /* The user could, in theory, have moved the file. So just show an empty window if that is the case. */
69 if (!filepath.has_value()) {
70 return;
71 }
72
73 this->filepath = filepath.value();
74 this->LoadTextfile(this->filepath, NO_DIRECTORY);
75 this->OnClick({ 0, 0 }, WID_TF_WRAPTEXT, 1);
76 }
77
78 void SetStringParameters(WidgetID widget) const override
79 {
80 if (widget == WID_TF_CAPTION) {
81 SetDParamStr(0, this->filename);
82 }
83 }
84
85 void AfterLoadText() override
86 {
87 if (this->filename == CHANGELOG_FILENAME) {
88 this->link_anchors.clear();
89 this->AfterLoadChangelog();
90 }
91 this->TextfileWindow::AfterLoadText();
92 }
93
99 void AfterLoadChangelog()
100 {
101 uint versions = 0;
102
103 /* Look for lines beginning with ###, they indicate a release name. */
104 for (size_t line_index = 0; line_index < this->lines.size(); ++line_index) {
105 const Line &line = this->lines[line_index];
106 if (!line.text.starts_with("###")) continue;
107
108 if (versions >= CHANGELOG_VERSIONS_LIMIT) {
109 this->lines.resize(line_index - 2);
110 break;
111 }
112
113 ++versions;
114 }
115 }
116};
117
119 struct HelpWindow : public Window {
120
121 HelpWindow(WindowDesc &desc, WindowNumber number) : Window(desc)
122 {
123 this->InitNested(number);
124
125 this->EnableTextfileButton(README_FILENAME, WID_HW_README);
126 this->EnableTextfileButton(CHANGELOG_FILENAME, WID_HW_CHANGELOG);
127 this->EnableTextfileButton(KNOWN_BUGS_FILENAME, WID_HW_KNOWN_BUGS);
128 this->EnableTextfileButton(LICENSE_FILENAME, WID_HW_LICENSE);
129 }
130
131 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
132 {
133 switch (widget) {
134 case WID_HW_README:
135 new GameManualTextfileWindow(README_FILENAME);
136 break;
137 case WID_HW_CHANGELOG:
138 new GameManualTextfileWindow(CHANGELOG_FILENAME);
139 break;
140 case WID_HW_KNOWN_BUGS:
141 new GameManualTextfileWindow(KNOWN_BUGS_FILENAME);
142 break;
143 case WID_HW_LICENSE:
144 new GameManualTextfileWindow(LICENSE_FILENAME);
145 break;
146 case WID_HW_WEBSITE:
147 OpenBrowser(WEBSITE_LINK);
148 break;
149 case WID_HW_WIKI:
150 OpenBrowser(WIKI_LINK);
151 break;
152 case WID_HW_BUGTRACKER:
153 OpenBrowser(BUGTRACKER_LINK);
154 break;
155 case WID_HW_COMMUNITY:
156 OpenBrowser(COMMUNITY_LINK);
157 break;
158 }
159 }
160
161private:
162 void EnableTextfileButton(std::string_view filename, WidgetID button_widget)
163 {
164 this->GetWidget<NWidgetLeaf>(button_widget)->SetDisabled(!FindGameManualFilePath(filename).has_value());
165 }
166};
167
168static constexpr NWidgetPart _nested_helpwin_widgets[] = {
169 NWidget(NWID_HORIZONTAL),
170 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
171 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_HELP_WINDOW_CAPTION, STR_NULL),
172 EndContainer(),
173
174 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
175 NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), SetPadding(WidgetDimensions::unscaled.sparse),
176 NWidget(WWT_FRAME, COLOUR_DARK_GREEN), SetDataTip(STR_HELP_WINDOW_WEBSITES, STR_NULL),
177 NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_HW_WEBSITE), SetDataTip(STR_HELP_WINDOW_MAIN_WEBSITE, STR_NULL), SetMinimalSize(128, 12), SetFill(1, 0),
178 NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_HW_WIKI), SetDataTip(STR_HELP_WINDOW_MANUAL_WIKI, STR_NULL), SetMinimalSize(128, 12), SetFill(1, 0),
179 NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_HW_BUGTRACKER), SetDataTip(STR_HELP_WINDOW_BUGTRACKER, STR_NULL), SetMinimalSize(128, 12), SetFill(1, 0),
180 NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_HW_COMMUNITY), SetDataTip(STR_HELP_WINDOW_COMMUNITY, STR_NULL), SetMinimalSize(128, 12), SetFill(1, 0),
181 EndContainer(),
182
183 NWidget(WWT_FRAME, COLOUR_DARK_GREEN), SetDataTip(STR_HELP_WINDOW_DOCUMENTS, STR_NULL),
184 NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_HW_README), SetDataTip(STR_HELP_WINDOW_README, STR_NULL), SetMinimalSize(128, 12), SetFill(1, 0),
185 NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_HW_CHANGELOG), SetDataTip(STR_HELP_WINDOW_CHANGELOG, STR_NULL), SetMinimalSize(128, 12), SetFill(1, 0),
186 NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_HW_KNOWN_BUGS),SetDataTip(STR_HELP_WINDOW_KNOWN_BUGS, STR_NULL), SetMinimalSize(128, 12), SetFill(1, 0),
187 NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_HW_LICENSE), SetDataTip(STR_HELP_WINDOW_LICENSE, STR_NULL), SetMinimalSize(128, 12), SetFill(1, 0),
188 EndContainer(),
189 EndContainer(),
190 EndContainer(),
191};
192
193static WindowDesc _helpwin_desc(
194 WDP_CENTER, nullptr, 0, 0,
195 WC_HELPWIN, WC_NONE,
196 0,
197 _nested_helpwin_widgets
198);
199
200void ShowHelpWindow()
201{
202 AllocateWindowDescFront<HelpWindow>(_helpwin_desc, 0);
203}
WidgetDimensions::unscaled
static const WidgetDimensions unscaled
Unscaled widget dimensions.
Definition window_gui.h:96
control_codes.h
Control codes that are embedded in the translation strings.
FioCheckFileExists
bool FioCheckFileExists(const std::string &filename, Subdirectory subdir)
Check whether the given file exists.
Definition fileio.cpp:121
fileio_func.h
Functions for Standard In/Out file operations.
Searchpath
Searchpath
Types of searchpaths OpenTTD might use.
Definition fileio_type.h:139
SP_SHARED_DIR
@ SP_SHARED_DIR
Search in the shared directory, like 'Shared Files' under Windows.
Definition fileio_type.h:146
SP_INSTALLATION_DIR
@ SP_INSTALLATION_DIR
Search in the installation directory.
Definition fileio_type.h:148
SP_BINARY_DIR
@ SP_BINARY_DIR
Search in the directory where the binary resides.
Definition fileio_type.h:147
SP_WORKING_DIR
@ SP_WORKING_DIR
Search in the working directory.
Definition fileio_type.h:141
SP_APPLICATION_BUNDLE_DIR
@ SP_APPLICATION_BUNDLE_DIR
Search within the application bundle.
Definition fileio_type.h:149
NO_DIRECTORY
@ NO_DIRECTORY
A path without any base directory.
Definition fileio_type.h:133
BASE_DIR
@ BASE_DIR
Base directory for all subdirectories.
Definition fileio_type.h:116
SetFill
constexpr NWidgetPart SetFill(uint16_t fill_x, uint16_t fill_y)
Widget part function for setting filling.
Definition widget_type.h:1181
SetPIP
constexpr NWidgetPart SetPIP(uint8_t pre, uint8_t inter, uint8_t post)
Widget part function for setting a pre/inter/post spaces.
Definition widget_type.h:1271
SetPadding
constexpr NWidgetPart SetPadding(uint8_t top, uint8_t right, uint8_t bottom, uint8_t left)
Widget part function for setting additional space around a widget.
Definition widget_type.h:1228
SetDataTip
constexpr NWidgetPart SetDataTip(uint32_t data, StringID tip)
Widget part function for setting the data and tooltip.
Definition widget_type.h:1202
SetMinimalSize
constexpr NWidgetPart SetMinimalSize(int16_t x, int16_t y)
Widget part function for setting the minimal size.
Definition widget_type.h:1137
NWidget
constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx=-1)
Widget part function for starting a new 'real' widget.
Definition widget_type.h:1320
EndContainer
constexpr NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
Definition widget_type.h:1191
gui.h
GUI functions that shouldn't be here.
FindGameManualFilePath
static std::optional< std::string > FindGameManualFilePath(std::string_view filename)
Find the path to the game manual file.
Definition help_gui.cpp:44
CHANGELOG_VERSIONS_LIMIT
static constexpr size_t CHANGELOG_VERSIONS_LIMIT
Only show the first 20 changelog versions in the textfile viewer.
Definition help_gui.cpp:36
help_gui.h
GUI to access manuals and related.
help_widget.h
Types related to the help window widgets.
misc_widget.h
Types related to the misc widgets.
WID_TF_WRAPTEXT
@ WID_TF_WRAPTEXT
Whether or not to wrap the text.
Definition misc_widget.h:53
WID_TF_CAPTION
@ WID_TF_CAPTION
The caption of the window.
Definition misc_widget.h:50
openttd.h
Some generic types.
safeguards.h
A number of safeguards to prevent using unsafe methods.
stdafx.h
Definition of base types and functions in a cross-platform compatible way.
string_func.h
Functions related to low-level strings.
SetDParamStr
void SetDParamStr(size_t n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
Definition strings.cpp:371
GameManualTextfileWindow
Window class displaying the game manual textfile viewer.
Definition help_gui.cpp:59
GameManualTextfileWindow::AfterLoadChangelog
void AfterLoadChangelog()
For changelog files, truncate the file after CHANGELOG_VERSIONS_LIMIT versions.
Definition help_gui.cpp:99
GameManualTextfileWindow::SetStringParameters
void SetStringParameters(WidgetID widget) const override
Initialize string parameters for a widget.
Definition help_gui.cpp:78
GameManualTextfileWindow::AfterLoadText
void AfterLoadText() override
Post-processing after the text is loaded.
Definition help_gui.cpp:85
HelpWindow
Window class displaying the help window.
Definition help_gui.cpp:119
HelpWindow::OnClick
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
Definition help_gui.cpp:131
NWidgetPart
Partial widget specification to allow NWidgets to be written nested.
Definition widget_type.h:1075
Point
Coordinates of a point in 2D.
Definition geometry_type.hpp:21
TextfileWindow::Line
Definition textfile_gui.h:46
TextfileWindow::Line::text
std::string text
Contents of the line.
Definition textfile_gui.h:49
TextfileWindow
Window for displaying a textfile.
Definition textfile_gui.h:21
TextfileWindow::trusted
bool trusted
Whether the content is trusted (read: not from content like NewGRFs, etc).
Definition textfile_gui.h:77
TextfileWindow::lines
std::vector< Line > lines
#text, split into lines in a table with lines.
Definition textfile_gui.h:71
TextfileWindow::OnClick
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
Definition textfile_gui.cpp:526
TextfileWindow::AfterLoadText
virtual void AfterLoadText()
Post-processing after the text is loaded.
Definition textfile_gui.cpp:497
TextfileWindow::filepath
std::string filepath
Full path to the filename.
Definition textfile_gui.h:69
TextfileWindow::link_anchors
std::vector< Hyperlink > link_anchors
Anchor names of headings that can be linked to.
Definition textfile_gui.h:74
TextfileWindow::filename
std::string filename
Filename of the textfile.
Definition textfile_gui.h:68
TextfileWindow::LoadTextfile
virtual void LoadTextfile(const std::string &textfile, Subdirectory dir)
Loads the textfile text from file and setup lines.
Definition textfile_gui.cpp:737
WindowDesc
High level window description.
Definition window_gui.h:159
Window
Data structure for an opened window.
Definition window_gui.h:273
Window::GetWidget
const NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
Definition window_gui.h:977
Window::InitNested
void InitNested(WindowNumber number=0)
Perform complete initialization of the Window with nested widgets, to allow use.
Definition window.cpp:1746
textfile_gui.h
GUI functions related to textfiles.
TFT_GAME_MANUAL
@ TFT_GAME_MANUAL
Game manual/documentation file.
Definition textfile_type.h:24
WWT_PUSHTXTBTN
@ WWT_PUSHTXTBTN
Normal push-button (no toggle button) with text caption.
Definition widget_type.h:113
NWID_HORIZONTAL
@ NWID_HORIZONTAL
Horizontal container.
Definition widget_type.h:75
WWT_PANEL
@ WWT_PANEL
Simple depressed panel.
Definition widget_type.h:50
WWT_CAPTION
@ WWT_CAPTION
Window caption (window title between closebox and stickybox)
Definition widget_type.h:61
WWT_CLOSEBOX
@ WWT_CLOSEBOX
Close box (at top-left of a window)
Definition widget_type.h:69
WWT_FRAME
@ WWT_FRAME
Frame.
Definition widget_type.h:60
window_gui.h
Functions, definitions and such used only by the GUI.
WDP_CENTER
@ WDP_CENTER
Center the window.
Definition window_gui.h:148
WidgetID
int WidgetID
Widget ID.
Definition window_type.h:18
WindowNumber
int32_t WindowNumber
Number to differentiate different windows of the same class.
Definition window_type.h:740
WC_NONE
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition window_type.h:45