(svn r23005) -Fix (r23004): Of course there's still the 16-sprite version for shore...
[openttd/fttd.git] / src / intro_gui.cpp
blob894f54dc473d8e7a1cd9c945ccbb9301315f0438
1 /* $Id$ */
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 */
10 /** @file intro_gui.cpp The main menu GUI. */
12 #include "stdafx.h"
13 #include "gui.h"
14 #include "window_gui.h"
15 #include "textbuf_gui.h"
16 #include "network/network.h"
17 #include "genworld.h"
18 #include "network/network_gui.h"
19 #include "network/network_content.h"
20 #include "landscape_type.h"
21 #include "strings_func.h"
22 #include "fios.h"
23 #include "ai/ai_gui.hpp"
24 #include "gfx_func.h"
25 #include "core/geometry_func.hpp"
26 #include "language.h"
27 #include "rev.h"
29 #include "table/strings.h"
30 #include "table/sprites.h"
32 enum SelectGameIntroWidgets {
33 SGI_GENERATE_GAME,
34 SGI_LOAD_GAME,
35 SGI_PLAY_SCENARIO,
36 SGI_PLAY_HEIGHTMAP,
37 SGI_EDIT_SCENARIO,
38 SGI_PLAY_NETWORK,
39 SGI_TEMPERATE_LANDSCAPE,
40 SGI_ARCTIC_LANDSCAPE,
41 SGI_TROPIC_LANDSCAPE,
42 SGI_TOYLAND_LANDSCAPE,
43 SGI_TRANSLATION_SELECTION,
44 SGI_TRANSLATION,
45 SGI_OPTIONS,
46 SGI_DIFFICULTIES,
47 SGI_SETTINGS_OPTIONS,
48 SGI_GRF_SETTINGS,
49 SGI_CONTENT_DOWNLOAD,
50 SGI_AI_SETTINGS,
51 SGI_EXIT,
54 struct SelectGameWindow : public Window {
56 SelectGameWindow(const WindowDesc *desc) : Window()
58 this->CreateNestedTree(desc);
59 this->FinishInitNested(desc, 0);
60 this->OnInvalidateData();
63 /**
64 * Some data on this window has become invalid.
65 * @param data Information about the changed data.
66 * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
68 virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
70 if (!gui_scope) return;
71 this->SetWidgetLoweredState(SGI_TEMPERATE_LANDSCAPE, _settings_newgame.game_creation.landscape == LT_TEMPERATE);
72 this->SetWidgetLoweredState(SGI_ARCTIC_LANDSCAPE, _settings_newgame.game_creation.landscape == LT_ARCTIC);
73 this->SetWidgetLoweredState(SGI_TROPIC_LANDSCAPE, _settings_newgame.game_creation.landscape == LT_TROPIC);
74 this->SetWidgetLoweredState(SGI_TOYLAND_LANDSCAPE, _settings_newgame.game_creation.landscape == LT_TOYLAND);
77 virtual void SetStringParameters(int widget) const
79 if (widget == SGI_DIFFICULTIES) SetDParam(0, STR_DIFFICULTY_LEVEL_EASY + _settings_newgame.difficulty.diff_level);
82 virtual void OnInit()
84 bool missing = _current_language->missing >= _settings_client.gui.missing_strings_threshold && !IsReleasedVersion();
85 this->GetWidget<NWidgetStacked>(SGI_TRANSLATION_SELECTION)->SetDisplayedPlane(missing ? 0 : SZSP_NONE);
88 virtual void DrawWidget(const Rect &r, int widget) const
90 switch (widget) {
91 case SGI_TRANSLATION:
92 SetDParam(0, _current_language->missing);
93 DrawStringMultiLine(r.left, r.right, r.top, r.bottom, STR_INTRO_TRANSLATION, TC_FROMSTRING, SA_CENTER);
94 break;
98 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
100 switch (widget) {
101 case SGI_DIFFICULTIES: {
102 Dimension textdim = {0, 0};
103 for (uint i = STR_DIFFICULTY_LEVEL_EASY; i <= STR_DIFFICULTY_LEVEL_CUSTOM; i++) {
104 SetDParam(0, i);
105 textdim = maxdim(textdim, GetStringBoundingBox(STR_INTRO_DIFFICULTY));
107 textdim.width += padding.width;
108 textdim.height += padding.height;
109 *size = maxdim(*size, textdim);
110 break;
113 case SGI_TRANSLATION: {
114 SetDParam(0, _current_language->missing);
115 int height = GetStringHeight(STR_INTRO_TRANSLATION, size->width);
116 if (height > 3 * FONT_HEIGHT_NORMAL) {
117 /* Don't let the window become too high. */
118 Dimension textdim = GetStringBoundingBox(STR_INTRO_TRANSLATION);
119 textdim.height *= 3;
120 textdim.width -= textdim.width / 2;
121 *size = maxdim(*size, textdim);
122 } else {
123 size->height = height + padding.height;
125 break;
130 virtual void OnClick(Point pt, int widget, int click_count)
132 #ifdef ENABLE_NETWORK
133 /* Do not create a network server when you (just) have closed one of the game
134 * creation/load windows for the network server. */
135 if (IsInsideMM(widget, SGI_GENERATE_GAME, SGI_EDIT_SCENARIO + 1)) _is_network_server = false;
136 #endif /* ENABLE_NETWORK */
138 switch (widget) {
139 case SGI_GENERATE_GAME:
140 if (_ctrl_pressed) {
141 StartNewGameWithoutGUI(GENERATE_NEW_SEED);
142 } else {
143 ShowGenerateLandscape();
145 break;
147 case SGI_LOAD_GAME: ShowSaveLoadDialog(SLD_LOAD_GAME); break;
148 case SGI_PLAY_SCENARIO: ShowSaveLoadDialog(SLD_LOAD_SCENARIO); break;
149 case SGI_PLAY_HEIGHTMAP: ShowSaveLoadDialog(SLD_LOAD_HEIGHTMAP); break;
150 case SGI_EDIT_SCENARIO: StartScenarioEditor(); break;
152 case SGI_PLAY_NETWORK:
153 if (!_network_available) {
154 ShowErrorMessage(STR_NETWORK_ERROR_NOTAVAILABLE, INVALID_STRING_ID, WL_ERROR);
155 } else {
156 ShowNetworkGameWindow();
158 break;
160 case SGI_TEMPERATE_LANDSCAPE: case SGI_ARCTIC_LANDSCAPE:
161 case SGI_TROPIC_LANDSCAPE: case SGI_TOYLAND_LANDSCAPE:
162 SetNewLandscapeType(widget - SGI_TEMPERATE_LANDSCAPE);
163 break;
165 case SGI_OPTIONS: ShowGameOptions(); break;
166 case SGI_DIFFICULTIES: ShowGameDifficulty(); break;
167 case SGI_SETTINGS_OPTIONS:ShowGameSettings(); break;
168 case SGI_GRF_SETTINGS: ShowNewGRFSettings(true, true, false, &_grfconfig_newgame); break;
169 case SGI_CONTENT_DOWNLOAD:
170 if (!_network_available) {
171 ShowErrorMessage(STR_NETWORK_ERROR_NOTAVAILABLE, INVALID_STRING_ID, WL_ERROR);
172 } else {
173 ShowNetworkContentListWindow();
175 break;
176 case SGI_AI_SETTINGS: ShowAIConfigWindow(); break;
177 case SGI_EXIT: HandleExitGameRequest(); break;
182 static const NWidgetPart _nested_select_game_widgets[] = {
183 NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_INTRO_CAPTION, STR_NULL),
184 NWidget(WWT_PANEL, COLOUR_BROWN),
185 NWidget(NWID_SPACER), SetMinimalSize(0, 8),
187 /* 'generate game' and 'load game' buttons */
188 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
189 NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, SGI_GENERATE_GAME), SetMinimalSize(158, 12),
190 SetDataTip(STR_INTRO_NEW_GAME, STR_INTRO_TOOLTIP_NEW_GAME), SetPadding(0, 0, 0, 10), SetFill(1, 0),
191 NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, SGI_LOAD_GAME), SetMinimalSize(158, 12),
192 SetDataTip(STR_INTRO_LOAD_GAME, STR_INTRO_TOOLTIP_LOAD_GAME), SetPadding(0, 10, 0, 0), SetFill(1, 0),
193 EndContainer(),
195 NWidget(NWID_SPACER), SetMinimalSize(0, 6),
197 /* 'play scenario' and 'play heightmap' buttons */
198 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
199 NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, SGI_PLAY_SCENARIO), SetMinimalSize(158, 12),
200 SetDataTip(STR_INTRO_PLAY_SCENARIO, STR_INTRO_TOOLTIP_PLAY_SCENARIO), SetPadding(0, 0, 0, 10), SetFill(1, 0),
201 NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, SGI_PLAY_HEIGHTMAP), SetMinimalSize(158, 12),
202 SetDataTip(STR_INTRO_PLAY_HEIGHTMAP, STR_INTRO_TOOLTIP_PLAY_HEIGHTMAP), SetPadding(0, 10, 0, 0), SetFill(1, 0),
203 EndContainer(),
205 NWidget(NWID_SPACER), SetMinimalSize(0, 6),
207 /* 'edit scenario' and 'play multiplayer' buttons */
208 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
209 NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, SGI_EDIT_SCENARIO), SetMinimalSize(158, 12),
210 SetDataTip(STR_INTRO_SCENARIO_EDITOR, STR_INTRO_TOOLTIP_SCENARIO_EDITOR), SetPadding(0, 0, 0, 10), SetFill(1, 0),
211 NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, SGI_PLAY_NETWORK), SetMinimalSize(158, 12),
212 SetDataTip(STR_INTRO_MULTIPLAYER, STR_INTRO_TOOLTIP_MULTIPLAYER), SetPadding(0, 10, 0, 0), SetFill(1, 0),
213 EndContainer(),
215 NWidget(NWID_SPACER), SetMinimalSize(0, 7),
217 /* climate selection buttons */
218 NWidget(NWID_HORIZONTAL),
219 NWidget(NWID_SPACER), SetMinimalSize(10, 0), SetFill(1, 0),
220 NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, SGI_TEMPERATE_LANDSCAPE), SetMinimalSize(77, 55),
221 SetDataTip(SPR_SELECT_TEMPERATE, STR_INTRO_TOOLTIP_TEMPERATE),
222 NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
223 NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, SGI_ARCTIC_LANDSCAPE), SetMinimalSize(77, 55),
224 SetDataTip(SPR_SELECT_SUB_ARCTIC, STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE),
225 NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
226 NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, SGI_TROPIC_LANDSCAPE), SetMinimalSize(77, 55),
227 SetDataTip(SPR_SELECT_SUB_TROPICAL, STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE),
228 NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
229 NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, SGI_TOYLAND_LANDSCAPE), SetMinimalSize(77, 55),
230 SetDataTip(SPR_SELECT_TOYLAND, STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE),
231 NWidget(NWID_SPACER), SetMinimalSize(10, 0), SetFill(1, 0),
232 EndContainer(),
234 NWidget(NWID_SPACER), SetMinimalSize(0, 7),
235 NWidget(NWID_SELECTION, INVALID_COLOUR, SGI_TRANSLATION_SELECTION),
236 NWidget(NWID_VERTICAL),
237 NWidget(WWT_EMPTY, COLOUR_ORANGE, SGI_TRANSLATION), SetMinimalSize(316, 12), SetFill(1, 0), SetPadding(0, 10, 7, 10),
238 EndContainer(),
239 EndContainer(),
241 /* 'game options' and 'difficulty options' buttons */
242 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
243 NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, SGI_OPTIONS), SetMinimalSize(158, 12),
244 SetDataTip(STR_INTRO_GAME_OPTIONS, STR_INTRO_TOOLTIP_GAME_OPTIONS), SetPadding(0, 0, 0, 10), SetFill(1, 0),
245 NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, SGI_DIFFICULTIES), SetMinimalSize(158, 12),
246 SetDataTip(STR_INTRO_DIFFICULTY, STR_INTRO_TOOLTIP_DIFFICULTY_OPTIONS), SetPadding(0, 10, 0, 0), SetFill(1, 0),
247 EndContainer(),
249 NWidget(NWID_SPACER), SetMinimalSize(0, 6),
251 /* 'advanced settings' and 'newgrf settings' buttons */
252 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
253 NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, SGI_SETTINGS_OPTIONS), SetMinimalSize(158, 12),
254 SetDataTip(STR_INTRO_ADVANCED_SETTINGS, STR_INTRO_TOOLTIP_ADVANCED_SETTINGS), SetPadding(0, 0, 0, 10), SetFill(1, 0),
255 NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, SGI_GRF_SETTINGS), SetMinimalSize(158, 12),
256 SetDataTip(STR_INTRO_NEWGRF_SETTINGS, STR_INTRO_TOOLTIP_NEWGRF_SETTINGS), SetPadding(0, 10, 0, 0), SetFill(1, 0),
257 EndContainer(),
259 NWidget(NWID_SPACER), SetMinimalSize(0, 6),
261 /* 'online content' and 'ai settings' buttons */
262 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
263 NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, SGI_CONTENT_DOWNLOAD), SetMinimalSize(158, 12),
264 SetDataTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT), SetPadding(0, 0, 0, 10), SetFill(1, 0),
265 NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, SGI_AI_SETTINGS), SetMinimalSize(158, 12),
266 SetDataTip(STR_INTRO_AI_SETTINGS, STR_INTRO_TOOLTIP_AI_SETTINGS), SetPadding(0, 10, 0, 0), SetFill(1, 0),
267 EndContainer(),
269 NWidget(NWID_SPACER), SetMinimalSize(0, 6),
271 /* 'exit program' button */
272 NWidget(NWID_HORIZONTAL),
273 NWidget(NWID_SPACER), SetFill(1, 0),
274 NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, SGI_EXIT), SetMinimalSize(128, 12),
275 SetDataTip(STR_INTRO_QUIT, STR_INTRO_TOOLTIP_QUIT),
276 NWidget(NWID_SPACER), SetFill(1, 0),
277 EndContainer(),
279 NWidget(NWID_SPACER), SetMinimalSize(0, 8),
281 EndContainer(),
284 static const WindowDesc _select_game_desc(
285 WDP_CENTER, 0, 0,
286 WC_SELECT_GAME, WC_NONE,
287 WDF_UNCLICK_BUTTONS,
288 _nested_select_game_widgets, lengthof(_nested_select_game_widgets)
291 void ShowSelectGameWindow()
293 new SelectGameWindow(&_select_game_desc);
296 static void AskExitGameCallback(Window *w, bool confirmed)
298 if (confirmed) _exit_game = true;
301 void AskExitGame()
303 #if defined(_WIN32)
304 SetDParam(0, STR_OSNAME_WINDOWS);
305 #elif defined(__APPLE__)
306 SetDParam(0, STR_OSNAME_OSX);
307 #elif defined(__BEOS__)
308 SetDParam(0, STR_OSNAME_BEOS);
309 #elif defined(__HAIKU__)
310 SetDParam(0, STR_OSNAME_HAIKU);
311 #elif defined(__MORPHOS__)
312 SetDParam(0, STR_OSNAME_MORPHOS);
313 #elif defined(__AMIGA__)
314 SetDParam(0, STR_OSNAME_AMIGAOS);
315 #elif defined(__OS2__)
316 SetDParam(0, STR_OSNAME_OS2);
317 #elif defined(SUNOS)
318 SetDParam(0, STR_OSNAME_SUNOS);
319 #elif defined(DOS)
320 SetDParam(0, STR_OSNAME_DOS);
321 #else
322 SetDParam(0, STR_OSNAME_UNIX);
323 #endif
324 ShowQuery(
325 STR_QUIT_CAPTION,
326 STR_QUIT_ARE_YOU_SURE_YOU_WANT_TO_EXIT_OPENTTD,
327 NULL,
328 AskExitGameCallback
333 static void AskExitToGameMenuCallback(Window *w, bool confirmed)
335 if (confirmed) _switch_mode = SM_MENU;
338 void AskExitToGameMenu()
340 ShowQuery(
341 STR_ABANDON_GAME_CAPTION,
342 (_game_mode != GM_EDITOR) ? STR_ABANDON_GAME_QUERY : STR_ABANDON_SCENARIO_QUERY,
343 NULL,
344 AskExitToGameMenuCallback