OpenTTD
intro_gui.cpp
Go to the documentation of this file.
1 /* $Id: intro_gui.cpp 27732 2017-01-14 18:30:26Z frosch $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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/>.
8  */
9 
12 #include "stdafx.h"
13 #include "error.h"
14 #include "gui.h"
15 #include "window_gui.h"
16 #include "textbuf_gui.h"
17 #include "network/network.h"
18 #include "genworld.h"
19 #include "network/network_gui.h"
21 #include "landscape_type.h"
22 #include "strings_func.h"
23 #include "fios.h"
24 #include "ai/ai_gui.hpp"
25 #include "gfx_func.h"
26 #include "core/geometry_func.hpp"
27 #include "language.h"
28 #include "rev.h"
29 #include "highscore.h"
30 
31 #include "widgets/intro_widget.h"
32 
33 #include "table/strings.h"
34 #include "table/sprites.h"
35 
36 #include "safeguards.h"
37 
38 struct SelectGameWindow : public Window {
39 
40  SelectGameWindow(WindowDesc *desc) : Window(desc)
41  {
42  this->CreateNestedTree();
43  this->FinishInitNested(0);
44  this->OnInvalidateData();
45  }
46 
52  virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
53  {
54  if (!gui_scope) return;
59  }
60 
61  virtual void OnInit()
62  {
63  bool missing_sprites = _missing_extra_graphics > 0 && !IsReleasedVersion();
64  this->GetWidget<NWidgetStacked>(WID_SGI_BASESET_SELECTION)->SetDisplayedPlane(missing_sprites ? 0 : SZSP_NONE);
65 
66  bool missing_lang = _current_language->missing >= _settings_client.gui.missing_strings_threshold && !IsReleasedVersion();
67  this->GetWidget<NWidgetStacked>(WID_SGI_TRANSLATION_SELECTION)->SetDisplayedPlane(missing_lang ? 0 : SZSP_NONE);
68  }
69 
70  virtual void DrawWidget(const Rect &r, int widget) const
71  {
72  switch (widget) {
73  case WID_SGI_BASESET:
75  DrawStringMultiLine(r.left, r.right, r.top, r.bottom, STR_INTRO_BASESET, TC_FROMSTRING, SA_CENTER);
76  break;
77 
80  DrawStringMultiLine(r.left, r.right, r.top, r.bottom, STR_INTRO_TRANSLATION, TC_FROMSTRING, SA_CENTER);
81  break;
82  }
83  }
84 
85  virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
86  {
87  StringID str = 0;
88  switch (widget) {
89  case WID_SGI_BASESET:
91  str = STR_INTRO_BASESET;
92  break;
93 
96  str = STR_INTRO_TRANSLATION;
97  break;
98  }
99 
100  if (str != 0) {
101  int height = GetStringHeight(str, size->width);
102  if (height > 3 * FONT_HEIGHT_NORMAL) {
103  /* Don't let the window become too high. */
104  Dimension textdim = GetStringBoundingBox(str);
105  textdim.height *= 3;
106  textdim.width -= textdim.width / 2;
107  *size = maxdim(*size, textdim);
108  } else {
109  size->height = height + padding.height;
110  }
111  }
112  }
113 
114  virtual void OnClick(Point pt, int widget, int click_count)
115  {
116 #ifdef ENABLE_NETWORK
117  /* Do not create a network server when you (just) have closed one of the game
118  * creation/load windows for the network server. */
120 #endif /* ENABLE_NETWORK */
121 
122  switch (widget) {
124  if (_ctrl_pressed) {
126  } else {
128  }
129  break;
130 
135 
137  if (!_network_available) {
138  ShowErrorMessage(STR_NETWORK_ERROR_NOTAVAILABLE, INVALID_STRING_ID, WL_ERROR);
139  } else {
140  ShowNetworkGameWindow();
141  }
142  break;
143 
147  break;
148 
149  case WID_SGI_OPTIONS: ShowGameOptions(); break;
150  case WID_SGI_HIGHSCORE: ShowHighscoreTable(); break;
152  case WID_SGI_GRF_SETTINGS: ShowNewGRFSettings(true, true, false, &_grfconfig_newgame); break;
154  if (!_network_available) {
155  ShowErrorMessage(STR_NETWORK_ERROR_NOTAVAILABLE, INVALID_STRING_ID, WL_ERROR);
156  } else {
158  }
159  break;
161  case WID_SGI_EXIT: HandleExitGameRequest(); break;
162  }
163  }
164 };
165 
166 static const NWidgetPart _nested_select_game_widgets[] = {
167  NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_INTRO_CAPTION, STR_NULL),
168  NWidget(WWT_PANEL, COLOUR_BROWN),
170 
171  /* 'generate game' and 'load game' buttons */
173  NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_GENERATE_GAME), SetMinimalSize(158, 12),
174  SetDataTip(STR_INTRO_NEW_GAME, STR_INTRO_TOOLTIP_NEW_GAME), SetPadding(0, 0, 0, 10), SetFill(1, 0),
175  NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_LOAD_GAME), SetMinimalSize(158, 12),
176  SetDataTip(STR_INTRO_LOAD_GAME, STR_INTRO_TOOLTIP_LOAD_GAME), SetPadding(0, 10, 0, 0), SetFill(1, 0),
177  EndContainer(),
178 
180 
181  /* 'play scenario' and 'play heightmap' buttons */
183  NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_PLAY_SCENARIO), SetMinimalSize(158, 12),
184  SetDataTip(STR_INTRO_PLAY_SCENARIO, STR_INTRO_TOOLTIP_PLAY_SCENARIO), SetPadding(0, 0, 0, 10), SetFill(1, 0),
185  NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_PLAY_HEIGHTMAP), SetMinimalSize(158, 12),
186  SetDataTip(STR_INTRO_PLAY_HEIGHTMAP, STR_INTRO_TOOLTIP_PLAY_HEIGHTMAP), SetPadding(0, 10, 0, 0), SetFill(1, 0),
187  EndContainer(),
188 
190 
191  /* 'edit scenario' and 'play multiplayer' buttons */
193  NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_EDIT_SCENARIO), SetMinimalSize(158, 12),
194  SetDataTip(STR_INTRO_SCENARIO_EDITOR, STR_INTRO_TOOLTIP_SCENARIO_EDITOR), SetPadding(0, 0, 0, 10), SetFill(1, 0),
195  NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_PLAY_NETWORK), SetMinimalSize(158, 12),
196  SetDataTip(STR_INTRO_MULTIPLAYER, STR_INTRO_TOOLTIP_MULTIPLAYER), SetPadding(0, 10, 0, 0), SetFill(1, 0),
197  EndContainer(),
198 
200 
201  /* climate selection buttons */
203  NWidget(NWID_SPACER), SetMinimalSize(10, 0), SetFill(1, 0),
205  SetDataTip(SPR_SELECT_TEMPERATE, STR_INTRO_TOOLTIP_TEMPERATE),
206  NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
208  SetDataTip(SPR_SELECT_SUB_ARCTIC, STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE),
209  NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
211  SetDataTip(SPR_SELECT_SUB_TROPICAL, STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE),
212  NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
214  SetDataTip(SPR_SELECT_TOYLAND, STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE),
215  NWidget(NWID_SPACER), SetMinimalSize(10, 0), SetFill(1, 0),
216  EndContainer(),
217 
221  NWidget(WWT_EMPTY, COLOUR_ORANGE, WID_SGI_BASESET), SetMinimalSize(316, 12), SetFill(1, 0), SetPadding(0, 10, 7, 10),
222  EndContainer(),
223  EndContainer(),
226  NWidget(WWT_EMPTY, COLOUR_ORANGE, WID_SGI_TRANSLATION), SetMinimalSize(316, 12), SetFill(1, 0), SetPadding(0, 10, 7, 10),
227  EndContainer(),
228  EndContainer(),
229 
230  /* 'game options' and 'advanced settings' buttons */
232  NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_OPTIONS), SetMinimalSize(158, 12),
233  SetDataTip(STR_INTRO_GAME_OPTIONS, STR_INTRO_TOOLTIP_GAME_OPTIONS), SetPadding(0, 0, 0, 10), SetFill(1, 0),
235  SetDataTip(STR_INTRO_CONFIG_SETTINGS_TREE, STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE), SetPadding(0, 10, 0, 0), SetFill(1, 0),
236  EndContainer(),
237 
239 
240  /* 'script settings' and 'newgrf settings' buttons */
242  NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_AI_SETTINGS), SetMinimalSize(158, 12),
243  SetDataTip(STR_INTRO_SCRIPT_SETTINGS, STR_INTRO_TOOLTIP_SCRIPT_SETTINGS), SetPadding(0, 0, 0, 10), SetFill(1, 0),
244  NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_GRF_SETTINGS), SetMinimalSize(158, 12),
245  SetDataTip(STR_INTRO_NEWGRF_SETTINGS, STR_INTRO_TOOLTIP_NEWGRF_SETTINGS), SetPadding(0, 10, 0, 0), SetFill(1, 0),
246  EndContainer(),
247 
249 
250  /* 'online content' and 'highscore' buttons */
253  SetDataTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT), SetPadding(0, 0, 0, 10), SetFill(1, 0),
254  NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_HIGHSCORE), SetMinimalSize(158, 12),
255  SetDataTip(STR_INTRO_HIGHSCORE, STR_INTRO_TOOLTIP_HIGHSCORE), SetPadding(0, 10, 0, 0), SetFill(1, 0),
256  EndContainer(),
257 
259 
260  /* 'exit program' button */
262  NWidget(NWID_SPACER), SetFill(1, 0),
263  NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_EXIT), SetMinimalSize(128, 12),
264  SetDataTip(STR_INTRO_QUIT, STR_INTRO_TOOLTIP_QUIT),
265  NWidget(NWID_SPACER), SetFill(1, 0),
266  EndContainer(),
267 
269 
270  EndContainer(),
271 };
272 
273 static WindowDesc _select_game_desc(
274  WDP_CENTER, NULL, 0, 0,
276  0,
277  _nested_select_game_widgets, lengthof(_nested_select_game_widgets)
278 );
279 
280 void ShowSelectGameWindow()
281 {
282  new SelectGameWindow(&_select_game_desc);
283 }
284 
285 static void AskExitGameCallback(Window *w, bool confirmed)
286 {
287  if (confirmed) _exit_game = true;
288 }
289 
290 void AskExitGame()
291 {
292 #if defined(_WIN32)
293  SetDParam(0, STR_OSNAME_WINDOWS);
294 #elif defined(__APPLE__)
295  SetDParam(0, STR_OSNAME_OSX);
296 #elif defined(__BEOS__)
297  SetDParam(0, STR_OSNAME_BEOS);
298 #elif defined(__HAIKU__)
299  SetDParam(0, STR_OSNAME_HAIKU);
300 #elif defined(__MORPHOS__)
301  SetDParam(0, STR_OSNAME_MORPHOS);
302 #elif defined(__AMIGA__)
303  SetDParam(0, STR_OSNAME_AMIGAOS);
304 #elif defined(__OS2__)
305  SetDParam(0, STR_OSNAME_OS2);
306 #elif defined(SUNOS)
307  SetDParam(0, STR_OSNAME_SUNOS);
308 #elif defined(DOS)
309  SetDParam(0, STR_OSNAME_DOS);
310 #else
311  SetDParam(0, STR_OSNAME_UNIX);
312 #endif
313  ShowQuery(
314  STR_QUIT_CAPTION,
315  STR_QUIT_ARE_YOU_SURE_YOU_WANT_TO_EXIT_OPENTTD,
316  NULL,
317  AskExitGameCallback
318  );
319 }
320 
321 
322 static void AskExitToGameMenuCallback(Window *w, bool confirmed)
323 {
324  if (confirmed) {
327  }
328 }
329 
330 void AskExitToGameMenu()
331 {
332  ShowQuery(
333  STR_ABANDON_GAME_CAPTION,
334  (_game_mode != GM_EDITOR) ? STR_ABANDON_GAME_QUERY : STR_ABANDON_SCENARIO_QUERY,
335  NULL,
336  AskExitToGameMenuCallback
337  );
338 }