|
1 /* $Id$ */ |
|
2 |
|
3 /** @file toolbar_gui.cpp Code related to the (main) toolbar. */ |
|
4 |
|
5 #include "stdafx.h" |
|
6 #include "openttd.h" |
|
7 #include "gui.h" |
|
8 #include "window_gui.h" |
|
9 #include "window_func.h" |
|
10 #include "viewport_func.h" |
|
11 #include "command_func.h" |
|
12 #include "variables.h" |
|
13 #include "train.h" |
|
14 #include "roadveh.h" |
|
15 #include "vehicle_gui.h" |
|
16 #include "rail_gui.h" |
|
17 #include "road_gui.h" |
|
18 #include "date_func.h" |
|
19 #include "vehicle_func.h" |
|
20 #include "sound_func.h" |
|
21 #include "terraform_gui.h" |
|
22 #include "transparency.h" |
|
23 #include "strings_func.h" |
|
24 #include "player_base.h" |
|
25 #include "player_func.h" |
|
26 #include "player_gui.h" |
|
27 #include "settings_type.h" |
|
28 #include "toolbar_gui.h" |
|
29 #include "vehicle_base.h" |
|
30 #include "gfx_func.h" |
|
31 |
|
32 #include "network/network.h" |
|
33 |
|
34 #include "table/strings.h" |
|
35 #include "table/sprites.h" |
|
36 |
|
37 extern void SelectSignTool(); |
|
38 extern RailType _last_built_railtype; |
|
39 extern RoadType _last_built_roadtype; |
|
40 |
|
41 /* Returns the position where the toolbar wants the menu to appear. |
|
42 * Make sure the dropdown is fully visible within the window. |
|
43 * x + w->left because x is supposed to be the offset of the toolbar-button |
|
44 * we clicked on and w->left the toolbar window itself. So meaning that |
|
45 * the default position is aligned with the left side of the clicked button */ |
|
46 Point GetToolbarDropdownPos(uint16 parent_button, int width, int height) |
|
47 { |
|
48 const Window *w = FindWindowById(WC_MAIN_TOOLBAR,0); |
|
49 Point pos; |
|
50 pos.x = w->widget[GB(parent_button, 0, 8)].left; |
|
51 pos.x = w->left + Clamp(pos.x, 0, w->width - width); |
|
52 pos.y = w->height; |
|
53 |
|
54 return pos; |
|
55 } |
|
56 |
|
57 |
|
58 static void ToolbarPauseClick(Window *w) |
|
59 { |
|
60 if (_networking && !_network_server) return; // only server can pause the game |
|
61 |
|
62 if (DoCommandP(0, _pause_game ? 0 : 1, 0, NULL, CMD_PAUSE)) SndPlayFx(SND_15_BEEP); |
|
63 } |
|
64 |
|
65 static void ToolbarFastForwardClick(Window *w) |
|
66 { |
|
67 _fast_forward ^= true; |
|
68 SndPlayFx(SND_15_BEEP); |
|
69 } |
|
70 |
|
71 static void ToolbarSaveClick(Window *w) |
|
72 { |
|
73 PopupMainToolbMenu(w, 3, STR_015C_SAVE_GAME, 4, 0); |
|
74 } |
|
75 |
|
76 static void ToolbarMapClick(Window *w) |
|
77 { |
|
78 PopupMainToolbMenu(w, 4, STR_02DE_MAP_OF_WORLD, 3, 0); |
|
79 } |
|
80 |
|
81 static void ToolbarTownClick(Window *w) |
|
82 { |
|
83 PopupMainToolbMenu(w, 5, STR_02BB_TOWN_DIRECTORY, 1, 0); |
|
84 } |
|
85 |
|
86 static void ToolbarSubsidiesClick(Window *w) |
|
87 { |
|
88 PopupMainToolbMenu(w, 6, STR_02DD_SUBSIDIES, 1, 0); |
|
89 } |
|
90 |
|
91 static void ToolbarStationsClick(Window *w) |
|
92 { |
|
93 PopupMainPlayerToolbMenu(w, 7, 0); |
|
94 } |
|
95 |
|
96 static void ToolbarMoneyClick(Window *w) |
|
97 { |
|
98 PopupMainPlayerToolbMenu(w, 8, 0); |
|
99 } |
|
100 |
|
101 static void ToolbarPlayersClick(Window *w) |
|
102 { |
|
103 PopupMainPlayerToolbMenu(w, 9, 0); |
|
104 } |
|
105 |
|
106 static void ToolbarGraphsClick(Window *w) |
|
107 { |
|
108 PopupMainToolbMenu(w, 10, STR_0154_OPERATING_PROFIT_GRAPH, 6, 0); |
|
109 } |
|
110 |
|
111 static void ToolbarLeagueClick(Window *w) |
|
112 { |
|
113 PopupMainToolbMenu(w, 11, STR_015A_COMPANY_LEAGUE_TABLE, 2, 0); |
|
114 } |
|
115 |
|
116 static void ToolbarIndustryClick(Window *w) |
|
117 { |
|
118 /* Disable build-industry menu if we are a spectator */ |
|
119 PopupMainToolbMenu(w, 12, STR_INDUSTRY_DIR, 2, (_current_player == PLAYER_SPECTATOR) ? (1 << 1) : 0); |
|
120 } |
|
121 |
|
122 static void ToolbarTrainClick(Window *w) |
|
123 { |
|
124 const Vehicle *v; |
|
125 int dis = -1; |
|
126 |
|
127 FOR_ALL_VEHICLES(v) { |
|
128 if (v->type == VEH_TRAIN && IsFrontEngine(v)) ClrBit(dis, v->owner); |
|
129 } |
|
130 PopupMainPlayerToolbMenu(w, 13, dis); |
|
131 } |
|
132 |
|
133 static void ToolbarRoadClick(Window *w) |
|
134 { |
|
135 const Vehicle *v; |
|
136 int dis = -1; |
|
137 |
|
138 FOR_ALL_VEHICLES(v) { |
|
139 if (v->type == VEH_ROAD && IsRoadVehFront(v)) ClrBit(dis, v->owner); |
|
140 } |
|
141 PopupMainPlayerToolbMenu(w, 14, dis); |
|
142 } |
|
143 |
|
144 static void ToolbarShipClick(Window *w) |
|
145 { |
|
146 const Vehicle *v; |
|
147 int dis = -1; |
|
148 |
|
149 FOR_ALL_VEHICLES(v) { |
|
150 if (v->type == VEH_SHIP) ClrBit(dis, v->owner); |
|
151 } |
|
152 PopupMainPlayerToolbMenu(w, 15, dis); |
|
153 } |
|
154 |
|
155 static void ToolbarAirClick(Window *w) |
|
156 { |
|
157 const Vehicle *v; |
|
158 int dis = -1; |
|
159 |
|
160 FOR_ALL_VEHICLES(v) { |
|
161 if (v->type == VEH_AIRCRAFT) ClrBit(dis, v->owner); |
|
162 } |
|
163 PopupMainPlayerToolbMenu(w, 16, dis); |
|
164 } |
|
165 |
|
166 |
|
167 static void ToolbarZoomInClick(Window *w) |
|
168 { |
|
169 if (DoZoomInOutWindow(ZOOM_IN, FindWindowById(WC_MAIN_WINDOW, 0))) { |
|
170 w->HandleButtonClick(17); |
|
171 SndPlayFx(SND_15_BEEP); |
|
172 } |
|
173 } |
|
174 |
|
175 static void ToolbarZoomOutClick(Window *w) |
|
176 { |
|
177 if (DoZoomInOutWindow(ZOOM_OUT,FindWindowById(WC_MAIN_WINDOW, 0))) { |
|
178 w->HandleButtonClick(18); |
|
179 SndPlayFx(SND_15_BEEP); |
|
180 } |
|
181 } |
|
182 |
|
183 static void ToolbarBuildRailClick(Window *w) |
|
184 { |
|
185 const Player *p = GetPlayer(_local_player); |
|
186 Window *w2 = PopupMainToolbMenu(w, 19, STR_1015_RAILROAD_CONSTRUCTION, RAILTYPE_END, ~p->avail_railtypes); |
|
187 WP(w2, menu_d).sel_index = _last_built_railtype; |
|
188 } |
|
189 |
|
190 static void ToolbarBuildRoadClick(Window *w) |
|
191 { |
|
192 const Player *p = GetPlayer(_local_player); |
|
193 /* The standard road button is *always* available */ |
|
194 Window *w2 = PopupMainToolbMenu(w, 20, STR_180A_ROAD_CONSTRUCTION, 2, ~(p->avail_roadtypes | ROADTYPES_ROAD)); |
|
195 WP(w2, menu_d).sel_index = _last_built_roadtype; |
|
196 } |
|
197 |
|
198 static void ToolbarBuildWaterClick(Window *w) |
|
199 { |
|
200 PopupMainToolbMenu(w, 21, STR_9800_DOCK_CONSTRUCTION, 1, 0); |
|
201 } |
|
202 |
|
203 static void ToolbarBuildAirClick(Window *w) |
|
204 { |
|
205 PopupMainToolbMenu(w, 22, STR_A01D_AIRPORT_CONSTRUCTION, 1, 0); |
|
206 } |
|
207 |
|
208 static void ToolbarForestClick(Window *w) |
|
209 { |
|
210 PopupMainToolbMenu(w, 23, STR_LANDSCAPING, 3, 0); |
|
211 } |
|
212 |
|
213 static void ToolbarMusicClick(Window *w) |
|
214 { |
|
215 PopupMainToolbMenu(w, 24, STR_01D3_SOUND_MUSIC, 1, 0); |
|
216 } |
|
217 |
|
218 static void ToolbarNewspaperClick(Window *w) |
|
219 { |
|
220 PopupMainToolbMenu(w, 25, STR_0200_LAST_MESSAGE_NEWS_REPORT, 3, 0); |
|
221 } |
|
222 |
|
223 static void ToolbarHelpClick(Window *w) |
|
224 { |
|
225 PopupMainToolbMenu(w, 26, STR_02D5_LAND_BLOCK_INFO, 6, 0); |
|
226 } |
|
227 |
|
228 static void ToolbarOptionsClick(Window *w) |
|
229 { |
|
230 uint16 x = 0; |
|
231 |
|
232 w = PopupMainToolbMenu(w, 2, STR_02C4_GAME_OPTIONS, 14, 0); |
|
233 |
|
234 if (HasBit(_display_opt, DO_SHOW_TOWN_NAMES)) SetBit(x, 6); |
|
235 if (HasBit(_display_opt, DO_SHOW_STATION_NAMES)) SetBit(x, 7); |
|
236 if (HasBit(_display_opt, DO_SHOW_SIGNS)) SetBit(x, 8); |
|
237 if (HasBit(_display_opt, DO_WAYPOINTS)) SetBit(x, 9); |
|
238 if (HasBit(_display_opt, DO_FULL_ANIMATION)) SetBit(x, 10); |
|
239 if (HasBit(_display_opt, DO_FULL_DETAIL)) SetBit(x, 11); |
|
240 if (IsTransparencySet(TO_HOUSES)) SetBit(x, 12); |
|
241 if (IsTransparencySet(TO_SIGNS)) SetBit(x, 13); |
|
242 WP(w, menu_d).checked_items = x; |
|
243 } |
|
244 |
|
245 |
|
246 static void ToolbarScenSaveOrLoad(Window *w) |
|
247 { |
|
248 PopupMainToolbMenu(w, 3, STR_0292_SAVE_SCENARIO, 6, 0); |
|
249 } |
|
250 |
|
251 static void ToolbarScenDateBackward(Window *w) |
|
252 { |
|
253 /* don't allow too fast scrolling */ |
|
254 if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) { |
|
255 w->HandleButtonClick(6); |
|
256 SetWindowDirty(w); |
|
257 |
|
258 _patches_newgame.starting_year = Clamp(_patches_newgame.starting_year - 1, MIN_YEAR, MAX_YEAR); |
|
259 SetDate(ConvertYMDToDate(_patches_newgame.starting_year, 0, 1)); |
|
260 } |
|
261 _left_button_clicked = false; |
|
262 } |
|
263 |
|
264 static void ToolbarScenDateForward(Window *w) |
|
265 { |
|
266 /* don't allow too fast scrolling */ |
|
267 if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) { |
|
268 w->HandleButtonClick(7); |
|
269 SetWindowDirty(w); |
|
270 |
|
271 _patches_newgame.starting_year = Clamp(_patches_newgame.starting_year + 1, MIN_YEAR, MAX_YEAR); |
|
272 SetDate(ConvertYMDToDate(_patches_newgame.starting_year, 0, 1)); |
|
273 } |
|
274 _left_button_clicked = false; |
|
275 } |
|
276 |
|
277 static void ToolbarScenMapTownDir(Window *w) |
|
278 { |
|
279 /* Scenario editor button, *hack*hack* use different button to activate */ |
|
280 PopupMainToolbMenu(w, 8 | (17 << 8), STR_02DE_MAP_OF_WORLD, 4, 0); |
|
281 } |
|
282 |
|
283 static void ToolbarScenZoomIn(Window *w) |
|
284 { |
|
285 if (DoZoomInOutWindow(ZOOM_IN, FindWindowById(WC_MAIN_WINDOW, 0))) { |
|
286 w->HandleButtonClick(9); |
|
287 SndPlayFx(SND_15_BEEP); |
|
288 } |
|
289 } |
|
290 |
|
291 static void ToolbarScenZoomOut(Window *w) |
|
292 { |
|
293 if (DoZoomInOutWindow(ZOOM_OUT, FindWindowById(WC_MAIN_WINDOW, 0))) { |
|
294 w->HandleButtonClick(10); |
|
295 SndPlayFx(SND_15_BEEP); |
|
296 } |
|
297 } |
|
298 |
|
299 static void ToolbarScenGenLand(Window *w) |
|
300 { |
|
301 w->HandleButtonClick(11); |
|
302 SndPlayFx(SND_15_BEEP); |
|
303 |
|
304 ShowEditorTerraformToolbar(); |
|
305 } |
|
306 |
|
307 |
|
308 static void ToolbarScenGenTown(Window *w) |
|
309 { |
|
310 w->HandleButtonClick(12); |
|
311 SndPlayFx(SND_15_BEEP); |
|
312 ShowBuildTownWindow(); |
|
313 } |
|
314 |
|
315 static void ToolbarScenGenIndustry(Window *w) |
|
316 { |
|
317 w->HandleButtonClick(13); |
|
318 SndPlayFx(SND_15_BEEP); |
|
319 ShowBuildIndustryWindow(); |
|
320 } |
|
321 |
|
322 static void ToolbarScenBuildRoad(Window *w) |
|
323 { |
|
324 w->HandleButtonClick(14); |
|
325 SndPlayFx(SND_15_BEEP); |
|
326 ShowBuildRoadScenToolbar(); |
|
327 } |
|
328 |
|
329 static void ToolbarScenPlantTrees(Window *w) |
|
330 { |
|
331 w->HandleButtonClick(15); |
|
332 SndPlayFx(SND_15_BEEP); |
|
333 ShowBuildTreesScenToolbar(); |
|
334 } |
|
335 |
|
336 static void ToolbarScenPlaceSign(Window *w) |
|
337 { |
|
338 w->HandleButtonClick(16); |
|
339 SndPlayFx(SND_15_BEEP); |
|
340 SelectSignTool(); |
|
341 } |
|
342 |
|
343 static void ToolbarBtn_NULL(Window *w) |
|
344 { |
|
345 } |
|
346 |
|
347 |
|
348 typedef void ToolbarButtonProc(Window *w); |
|
349 |
|
350 static ToolbarButtonProc * const _toolbar_button_procs[] = { |
|
351 ToolbarPauseClick, |
|
352 ToolbarFastForwardClick, |
|
353 ToolbarOptionsClick, |
|
354 ToolbarSaveClick, |
|
355 ToolbarMapClick, |
|
356 ToolbarTownClick, |
|
357 ToolbarSubsidiesClick, |
|
358 ToolbarStationsClick, |
|
359 ToolbarMoneyClick, |
|
360 ToolbarPlayersClick, |
|
361 ToolbarGraphsClick, |
|
362 ToolbarLeagueClick, |
|
363 ToolbarIndustryClick, |
|
364 ToolbarTrainClick, |
|
365 ToolbarRoadClick, |
|
366 ToolbarShipClick, |
|
367 ToolbarAirClick, |
|
368 ToolbarZoomInClick, |
|
369 ToolbarZoomOutClick, |
|
370 ToolbarBuildRailClick, |
|
371 ToolbarBuildRoadClick, |
|
372 ToolbarBuildWaterClick, |
|
373 ToolbarBuildAirClick, |
|
374 ToolbarForestClick, |
|
375 ToolbarMusicClick, |
|
376 ToolbarNewspaperClick, |
|
377 ToolbarHelpClick, |
|
378 }; |
|
379 |
|
380 extern void MenuClickSmallScreenshot(); |
|
381 extern void MenuClickWorldScreenshot(); |
|
382 extern void MenuClickSaveLoad(int index); |
|
383 |
|
384 void MainToolbarWndProc(Window *w, WindowEvent *e) |
|
385 { |
|
386 switch (e->event) { |
|
387 case WE_PAINT: |
|
388 /* Draw brown-red toolbar bg. */ |
|
389 GfxFillRect(0, 0, w->width-1, w->height-1, 0xB2); |
|
390 GfxFillRect(0, 0, w->width-1, w->height-1, 0xB4 | (1 << PALETTE_MODIFIER_GREYOUT)); |
|
391 |
|
392 /* If spectator, disable all construction buttons |
|
393 * ie : Build road, rail, ships, airports and landscaping |
|
394 * Since enabled state is the default, just disable when needed */ |
|
395 w->SetWidgetsDisabledState(_current_player == PLAYER_SPECTATOR, 19, 20, 21, 22, 23, WIDGET_LIST_END); |
|
396 /* disable company list drop downs, if there are no companies */ |
|
397 w->SetWidgetsDisabledState(ActivePlayerCount() == 0, 7, 8, 13, 14, 15, 16, WIDGET_LIST_END); |
|
398 |
|
399 w->SetWidgetDisabledState(19, !CanBuildVehicleInfrastructure(VEH_TRAIN)); |
|
400 w->SetWidgetDisabledState(22, !CanBuildVehicleInfrastructure(VEH_AIRCRAFT)); |
|
401 |
|
402 DrawWindowWidgets(w); |
|
403 break; |
|
404 |
|
405 case WE_CLICK: |
|
406 if (_game_mode != GM_MENU && !w->IsWidgetDisabled(e->we.click.widget)) |
|
407 _toolbar_button_procs[e->we.click.widget](w); |
|
408 break; |
|
409 |
|
410 case WE_KEYPRESS: |
|
411 switch (e->we.keypress.keycode) { |
|
412 case WKC_F1: case WKC_PAUSE: ToolbarPauseClick(w); break; |
|
413 case WKC_F2: ShowGameOptions(); break; |
|
414 case WKC_F3: MenuClickSaveLoad(0); break; |
|
415 case WKC_F4: ShowSmallMap(); break; |
|
416 case WKC_F5: ShowTownDirectory(); break; |
|
417 case WKC_F6: ShowSubsidiesList(); break; |
|
418 case WKC_F7: ShowPlayerStations(_local_player); break; |
|
419 case WKC_F8: ShowPlayerFinances(_local_player); break; |
|
420 case WKC_F9: ShowPlayerCompany(_local_player); break; |
|
421 case WKC_F10: ShowOperatingProfitGraph(); break; |
|
422 case WKC_F11: ShowCompanyLeagueTable(); break; |
|
423 case WKC_F12: ShowBuildIndustryWindow(); break; |
|
424 case WKC_SHIFT | WKC_F1: ShowVehicleListWindow(_local_player, VEH_TRAIN); break; |
|
425 case WKC_SHIFT | WKC_F2: ShowVehicleListWindow(_local_player, VEH_ROAD); break; |
|
426 case WKC_SHIFT | WKC_F3: ShowVehicleListWindow(_local_player, VEH_SHIP); break; |
|
427 case WKC_SHIFT | WKC_F4: ShowVehicleListWindow(_local_player, VEH_AIRCRAFT); break; |
|
428 case WKC_NUM_PLUS: // Fall through |
|
429 case WKC_EQUALS: // Fall through |
|
430 case WKC_SHIFT | WKC_EQUALS: // Fall through |
|
431 case WKC_SHIFT | WKC_F5: ToolbarZoomInClick(w); break; |
|
432 case WKC_NUM_MINUS: // Fall through |
|
433 case WKC_MINUS: // Fall through |
|
434 case WKC_SHIFT | WKC_MINUS: // Fall through |
|
435 case WKC_SHIFT | WKC_F6: ToolbarZoomOutClick(w); break; |
|
436 case WKC_SHIFT | WKC_F7: if (CanBuildVehicleInfrastructure(VEH_TRAIN)) ShowBuildRailToolbar(_last_built_railtype, -1); break; |
|
437 case WKC_SHIFT | WKC_F8: ShowBuildRoadToolbar(_last_built_roadtype); break; |
|
438 case WKC_SHIFT | WKC_F9: ShowBuildDocksToolbar(); break; |
|
439 case WKC_SHIFT | WKC_F10: if (CanBuildVehicleInfrastructure(VEH_AIRCRAFT)) ShowBuildAirToolbar(); break; |
|
440 case WKC_SHIFT | WKC_F11: ShowBuildTreesToolbar(); break; |
|
441 case WKC_SHIFT | WKC_F12: ShowMusicWindow(); break; |
|
442 case WKC_CTRL | 'S': MenuClickSmallScreenshot(); break; |
|
443 case WKC_CTRL | 'G': MenuClickWorldScreenshot(); break; |
|
444 case WKC_CTRL | WKC_ALT | 'C': if (!_networking) ShowCheatWindow(); break; |
|
445 case 'A': if (CanBuildVehicleInfrastructure(VEH_TRAIN)) ShowBuildRailToolbar(_last_built_railtype, 4); break; // Invoke Autorail |
|
446 case 'L': ShowTerraformToolbar(); break; |
|
447 case 'M': ShowSmallMap(); break; |
|
448 case 'V': ShowExtraViewPortWindow(); break; |
|
449 default: return; |
|
450 } |
|
451 e->we.keypress.cont = false; |
|
452 break; |
|
453 |
|
454 case WE_PLACE_OBJ: |
|
455 _place_proc(e->we.place.tile); |
|
456 break; |
|
457 |
|
458 case WE_ABORT_PLACE_OBJ: |
|
459 w->RaiseWidget(25); |
|
460 SetWindowDirty(w); |
|
461 break; |
|
462 |
|
463 case WE_MOUSELOOP: |
|
464 if (w->IsWidgetLowered(0) != !!_pause_game) { |
|
465 w->ToggleWidgetLoweredState(0); |
|
466 w->InvalidateWidget(0); |
|
467 } |
|
468 |
|
469 if (w->IsWidgetLowered(1) != !!_fast_forward) { |
|
470 w->ToggleWidgetLoweredState(1); |
|
471 w->InvalidateWidget(1); |
|
472 } |
|
473 break; |
|
474 |
|
475 case WE_RESIZE: { |
|
476 /* There are 27 buttons plus some spacings if the space allows it */ |
|
477 uint button_width; |
|
478 uint spacing; |
|
479 if (w->width >= 27 * 22) { |
|
480 button_width = 22; |
|
481 spacing = w->width - (27 * button_width); |
|
482 } else { |
|
483 button_width = w->width / 27; |
|
484 spacing = 0; |
|
485 } |
|
486 uint extra_spacing_at[] = { 4, 8, 13, 17, 19, 24, 0 }; |
|
487 |
|
488 for (uint i = 0, x = 0, j = 0; i < 27; i++) { |
|
489 if (extra_spacing_at[j] == i) { |
|
490 j++; |
|
491 uint add = spacing / (lengthof(extra_spacing_at) - j); |
|
492 spacing -= add; |
|
493 x += add; |
|
494 } |
|
495 |
|
496 w->widget[i].left = x; |
|
497 x += (spacing != 0) ? button_width : (w->width - x) / (27 - i); |
|
498 w->widget[i].right = x - 1; |
|
499 } |
|
500 } break; |
|
501 |
|
502 case WE_TIMEOUT: |
|
503 for (uint i = 2; i < w->widget_count; i++) { |
|
504 if (w->IsWidgetLowered(i)) { |
|
505 w->RaiseWidget(i); |
|
506 w->InvalidateWidget(i); |
|
507 } |
|
508 } |
|
509 break; |
|
510 |
|
511 case WE_MESSAGE: |
|
512 if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(w, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, 17, 18); |
|
513 break; |
|
514 } |
|
515 } |
|
516 |
|
517 static const Widget _toolb_normal_widgets[] = { |
|
518 { WWT_IMGBTN, RESIZE_LEFT, 14, 0, 0, 0, 21, SPR_IMG_PAUSE, STR_0171_PAUSE_GAME}, |
|
519 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_FASTFORWARD, STR_FAST_FORWARD}, |
|
520 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_SETTINGS, STR_0187_OPTIONS}, |
|
521 { WWT_IMGBTN_2, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_SAVE, STR_0172_SAVE_GAME_ABANDON_GAME}, |
|
522 |
|
523 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_SMALLMAP, STR_0174_DISPLAY_MAP}, |
|
524 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_TOWN, STR_0176_DISPLAY_TOWN_DIRECTORY}, |
|
525 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_SUBSIDIES, STR_02DC_DISPLAY_SUBSIDIES}, |
|
526 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_COMPANY_LIST, STR_0173_DISPLAY_LIST_OF_COMPANY}, |
|
527 |
|
528 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_COMPANY_FINANCE, STR_0177_DISPLAY_COMPANY_FINANCES}, |
|
529 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_COMPANY_GENERAL, STR_0178_DISPLAY_COMPANY_GENERAL}, |
|
530 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_GRAPHS, STR_0179_DISPLAY_GRAPHS}, |
|
531 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_COMPANY_LEAGUE, STR_017A_DISPLAY_COMPANY_LEAGUE}, |
|
532 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_INDUSTRY, STR_0312_FUND_CONSTRUCTION_OF_NEW}, |
|
533 |
|
534 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_TRAINLIST, STR_017B_DISPLAY_LIST_OF_COMPANY}, |
|
535 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_TRUCKLIST, STR_017C_DISPLAY_LIST_OF_COMPANY}, |
|
536 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_SHIPLIST, STR_017D_DISPLAY_LIST_OF_COMPANY}, |
|
537 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_AIRPLANESLIST, STR_017E_DISPLAY_LIST_OF_COMPANY}, |
|
538 |
|
539 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_ZOOMIN, STR_017F_ZOOM_THE_VIEW_IN}, |
|
540 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_ZOOMOUT, STR_0180_ZOOM_THE_VIEW_OUT}, |
|
541 |
|
542 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_BUILDRAIL, STR_0181_BUILD_RAILROAD_TRACK}, |
|
543 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_BUILDROAD, STR_0182_BUILD_ROADS}, |
|
544 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_BUILDWATER, STR_0183_BUILD_SHIP_DOCKS}, |
|
545 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_BUILDAIR, STR_0184_BUILD_AIRPORTS}, |
|
546 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_LANDSCAPING, STR_LANDSCAPING_TOOLBAR_TIP}, // tree icon is 0x2E6 |
|
547 |
|
548 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_MUSIC, STR_01D4_SHOW_SOUND_MUSIC_WINDOW}, |
|
549 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_MESSAGES, STR_0203_SHOW_LAST_MESSAGE_NEWS}, |
|
550 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_QUERY, STR_0186_LAND_BLOCK_INFORMATION}, |
|
551 { WIDGETS_END}, |
|
552 }; |
|
553 |
|
554 static const WindowDesc _toolb_normal_desc = { |
|
555 0, 0, 0, 22, 640, 22, |
|
556 WC_MAIN_TOOLBAR, WC_NONE, |
|
557 WDF_STD_TOOLTIPS | WDF_DEF_WIDGET, |
|
558 _toolb_normal_widgets, |
|
559 MainToolbarWndProc |
|
560 }; |
|
561 |
|
562 |
|
563 static ToolbarButtonProc * const _scen_toolbar_button_procs[] = { |
|
564 ToolbarPauseClick, |
|
565 ToolbarFastForwardClick, |
|
566 ToolbarOptionsClick, |
|
567 ToolbarScenSaveOrLoad, |
|
568 ToolbarBtn_NULL, |
|
569 ToolbarBtn_NULL, |
|
570 ToolbarScenDateBackward, |
|
571 ToolbarScenDateForward, |
|
572 ToolbarScenMapTownDir, |
|
573 ToolbarScenZoomIn, |
|
574 ToolbarScenZoomOut, |
|
575 ToolbarScenGenLand, |
|
576 ToolbarScenGenTown, |
|
577 ToolbarScenGenIndustry, |
|
578 ToolbarScenBuildRoad, |
|
579 ToolbarScenPlantTrees, |
|
580 ToolbarScenPlaceSign, |
|
581 NULL, |
|
582 NULL, |
|
583 NULL, |
|
584 NULL, |
|
585 NULL, |
|
586 NULL, |
|
587 NULL, |
|
588 ToolbarMusicClick, |
|
589 NULL, |
|
590 ToolbarHelpClick, |
|
591 }; |
|
592 |
|
593 void ScenEditToolbarWndProc(Window *w, WindowEvent *e) |
|
594 { |
|
595 switch (e->event) { |
|
596 case WE_PAINT: |
|
597 w->SetWidgetDisabledState(6, _patches_newgame.starting_year <= MIN_YEAR); |
|
598 w->SetWidgetDisabledState(7, _patches_newgame.starting_year >= MAX_YEAR); |
|
599 |
|
600 /* Draw brown-red toolbar bg. */ |
|
601 GfxFillRect(0, 0, w->width-1, w->height-1, 0xB2); |
|
602 GfxFillRect(0, 0, w->width-1, w->height-1, 0xB4 | (1 << PALETTE_MODIFIER_GREYOUT)); |
|
603 |
|
604 DrawWindowWidgets(w); |
|
605 |
|
606 SetDParam(0, ConvertYMDToDate(_patches_newgame.starting_year, 0, 1)); |
|
607 DrawStringCenteredTruncated(w->widget[6].right, w->widget[7].left, 6, STR_00AF, TC_FROMSTRING); |
|
608 |
|
609 /* We hide this panel when the toolbar space gets too small */ |
|
610 if (w->widget[4].left != w->widget[4].right) { |
|
611 DrawStringCenteredTruncated(w->widget[4].left + 1, w->widget[4].right - 1, 1, STR_0221_OPENTTD, TC_FROMSTRING); |
|
612 DrawStringCenteredTruncated(w->widget[4].left + 1, w->widget[4].right - 1, 11, STR_0222_SCENARIO_EDITOR, TC_FROMSTRING); |
|
613 } |
|
614 |
|
615 break; |
|
616 |
|
617 case WE_CLICK: |
|
618 if (_game_mode == GM_MENU) return; |
|
619 _scen_toolbar_button_procs[e->we.click.widget](w); |
|
620 break; |
|
621 |
|
622 case WE_KEYPRESS: |
|
623 switch (e->we.keypress.keycode) { |
|
624 case WKC_F1: case WKC_PAUSE: ToolbarPauseClick(w); break; |
|
625 case WKC_F2: ShowGameOptions(); break; |
|
626 case WKC_F3: MenuClickSaveLoad(0); break; |
|
627 case WKC_F4: ToolbarScenGenLand(w); break; |
|
628 case WKC_F5: ToolbarScenGenTown(w); break; |
|
629 case WKC_F6: ToolbarScenGenIndustry(w); break; |
|
630 case WKC_F7: ToolbarScenBuildRoad(w); break; |
|
631 case WKC_F8: ToolbarScenPlantTrees(w); break; |
|
632 case WKC_F9: ToolbarScenPlaceSign(w); break; |
|
633 case WKC_F10: ShowMusicWindow(); break; |
|
634 case WKC_F11: PlaceLandBlockInfo(); break; |
|
635 case WKC_CTRL | 'S': MenuClickSmallScreenshot(); break; |
|
636 case WKC_CTRL | 'G': MenuClickWorldScreenshot(); break; |
|
637 |
|
638 /* those following are all fall through */ |
|
639 case WKC_NUM_PLUS: |
|
640 case WKC_EQUALS: |
|
641 case WKC_SHIFT | WKC_EQUALS: |
|
642 case WKC_SHIFT | WKC_F5: ToolbarZoomInClick(w); break; |
|
643 |
|
644 /* those following are all fall through */ |
|
645 case WKC_NUM_MINUS: |
|
646 case WKC_MINUS: |
|
647 case WKC_SHIFT | WKC_MINUS: |
|
648 case WKC_SHIFT | WKC_F6: ToolbarZoomOutClick(w); break; |
|
649 |
|
650 case 'L': ShowEditorTerraformToolbar(); break; |
|
651 case 'M': ShowSmallMap(); break; |
|
652 case 'V': ShowExtraViewPortWindow(); break; |
|
653 default: return; |
|
654 } |
|
655 e->we.keypress.cont = false; |
|
656 break; |
|
657 |
|
658 case WE_PLACE_OBJ: |
|
659 _place_proc(e->we.place.tile); |
|
660 break; |
|
661 |
|
662 case WE_ABORT_PLACE_OBJ: |
|
663 w->RaiseWidget(25); |
|
664 SetWindowDirty(w); |
|
665 break; |
|
666 |
|
667 case WE_RESIZE: { |
|
668 /* There are 15 buttons plus some spacings if the space allows it. |
|
669 * Furthermore there are two panels of which one is non-essential |
|
670 * and that one can be removed is the space is too small. */ |
|
671 uint buttons_width; |
|
672 uint spacing; |
|
673 |
|
674 static int normal_min_width = (15 * 22) + (2 * 130); |
|
675 static int one_less_panel_min_width = (15 * 22) + 130; |
|
676 |
|
677 if (w->width >= one_less_panel_min_width) { |
|
678 buttons_width = 15 * 22; |
|
679 spacing = w->width - ((w->width >= normal_min_width) ? normal_min_width : one_less_panel_min_width); |
|
680 } else { |
|
681 buttons_width = w->width - 130; |
|
682 spacing = 0; |
|
683 } |
|
684 uint extra_spacing_at[] = { 3, 4, 7, 8, 10, 16, 0 }; |
|
685 |
|
686 /* Yes, it defines about 27 widgets for this toolbar */ |
|
687 for (uint i = 0, x = 0, j = 0, b = 0; i < 27; i++) { |
|
688 switch (i) { |
|
689 case 4: |
|
690 w->widget[i].left = x; |
|
691 if (w->width < normal_min_width) { |
|
692 w->widget[i].right = x; |
|
693 j++; |
|
694 continue; |
|
695 } |
|
696 |
|
697 x += 130; |
|
698 w->widget[i].right = x - 1; |
|
699 break; |
|
700 |
|
701 case 5: { |
|
702 int offset = x - w->widget[i].left; |
|
703 w->widget[i + 1].left += offset; |
|
704 w->widget[i + 1].right += offset; |
|
705 w->widget[i + 2].left += offset; |
|
706 w->widget[i + 2].right += offset; |
|
707 w->widget[i].left = x; |
|
708 x += 130; |
|
709 w->widget[i].right = x - 1; |
|
710 i += 2; |
|
711 } break; |
|
712 |
|
713 default: |
|
714 if (w->widget[i].bottom == 0) continue; |
|
715 |
|
716 w->widget[i].left = x; |
|
717 x += buttons_width / (15 - b); |
|
718 w->widget[i].right = x - 1; |
|
719 buttons_width -= buttons_width / (15 - b); |
|
720 b++; |
|
721 break; |
|
722 } |
|
723 |
|
724 if (extra_spacing_at[j] == i) { |
|
725 j++; |
|
726 uint add = spacing / (lengthof(extra_spacing_at) - j); |
|
727 spacing -= add; |
|
728 x += add; |
|
729 } |
|
730 } |
|
731 } break; |
|
732 |
|
733 case WE_MOUSELOOP: |
|
734 if (w->IsWidgetLowered(0) != !!_pause_game) { |
|
735 w->ToggleWidgetLoweredState(0); |
|
736 SetWindowDirty(w); |
|
737 } |
|
738 |
|
739 if (w->IsWidgetLowered(1) != !!_fast_forward) { |
|
740 w->ToggleWidgetLoweredState(1); |
|
741 SetWindowDirty(w); |
|
742 } |
|
743 break; |
|
744 |
|
745 case WE_MESSAGE: |
|
746 HandleZoomMessage(w, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, 9, 10); |
|
747 break; |
|
748 } |
|
749 } |
|
750 |
|
751 static const Widget _toolb_scen_widgets[] = { |
|
752 { WWT_IMGBTN, RESIZE_LEFT, 14, 0, 0, 0, 21, SPR_IMG_PAUSE, STR_0171_PAUSE_GAME}, |
|
753 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_FASTFORWARD, STR_FAST_FORWARD}, |
|
754 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_SETTINGS, STR_0187_OPTIONS}, |
|
755 {WWT_IMGBTN_2, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_SAVE, STR_0297_SAVE_SCENARIO_LOAD_SCENARIO}, |
|
756 |
|
757 { WWT_PANEL, RESIZE_NONE, 14, 0, 0, 0, 21, 0x0, STR_NULL}, |
|
758 |
|
759 { WWT_PANEL, RESIZE_NONE, 14, 0, 129, 0, 21, 0x0, STR_NULL}, |
|
760 { WWT_IMGBTN, RESIZE_NONE, 14, 3, 14, 5, 16, SPR_ARROW_DOWN, STR_029E_MOVE_THE_STARTING_DATE}, |
|
761 { WWT_IMGBTN, RESIZE_NONE, 14, 113, 125, 5, 16, SPR_ARROW_UP, STR_029F_MOVE_THE_STARTING_DATE}, |
|
762 |
|
763 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_SMALLMAP, STR_0175_DISPLAY_MAP_TOWN_DIRECTORY}, |
|
764 |
|
765 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_ZOOMIN, STR_017F_ZOOM_THE_VIEW_IN}, |
|
766 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_ZOOMOUT, STR_0180_ZOOM_THE_VIEW_OUT}, |
|
767 |
|
768 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_LANDSCAPING, STR_022E_LANDSCAPE_GENERATION}, |
|
769 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_TOWN, STR_022F_TOWN_GENERATION}, |
|
770 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_INDUSTRY, STR_0230_INDUSTRY_GENERATION}, |
|
771 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_BUILDROAD, STR_0231_ROAD_CONSTRUCTION}, |
|
772 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_PLANTTREES, STR_0288_PLANT_TREES}, |
|
773 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_SIGN, STR_0289_PLACE_SIGN}, |
|
774 |
|
775 { WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL}, |
|
776 { WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL}, |
|
777 { WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL}, |
|
778 { WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL}, |
|
779 { WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL}, |
|
780 { WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL}, |
|
781 { WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL}, |
|
782 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_MUSIC, STR_01D4_SHOW_SOUND_MUSIC_WINDOW}, |
|
783 { WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL}, |
|
784 { WWT_IMGBTN, RESIZE_NONE, 14, 0, 0, 0, 21, SPR_IMG_QUERY, STR_0186_LAND_BLOCK_INFORMATION}, |
|
785 {WIDGETS_END}, |
|
786 }; |
|
787 |
|
788 static const WindowDesc _toolb_scen_desc = { |
|
789 0, 0, 130, 22, 640, 22, |
|
790 WC_MAIN_TOOLBAR, WC_NONE, |
|
791 WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS, |
|
792 _toolb_scen_widgets, |
|
793 ScenEditToolbarWndProc |
|
794 }; |
|
795 |
|
796 Window *AllocateToolbar() |
|
797 { |
|
798 return AllocateWindowDesc((_game_mode != GM_EDITOR) ? &_toolb_normal_desc : &_toolb_scen_desc); |
|
799 } |