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/>.
8 /** @file toolbar_gui.cpp Code related to the (main) toolbar. */
12 #include "window_gui.h"
13 #include "window_func.h"
14 #include "viewport_func.h"
15 #include "command_func.h"
16 #include "dropdown_type.h"
17 #include "dropdown_func.h"
18 #include "dropdown_common_type.h"
20 #include "vehicle_gui.h"
24 #include "vehicle_func.h"
25 #include "sound_func.h"
26 #include "terraform_gui.h"
27 #include "strings_func.h"
28 #include "company_func.h"
29 #include "company_gui.h"
30 #include "vehicle_base.h"
31 #include "cheat_func.h"
32 #include "transparency_gui.h"
33 #include "screenshot.h"
34 #include "signs_func.h"
36 #include "console_gui.h"
38 #include "ai/ai_gui.hpp"
39 #include "game/game_gui.hpp"
40 #include "script/script_gui.h"
41 #include "tilehighlight_func.h"
42 #include "smallmap_gui.h"
43 #include "graph_gui.h"
44 #include "textbuf_gui.h"
45 #include "linkgraph/linkgraph_gui.h"
46 #include "newgrf_debug.h"
48 #include "engine_base.h"
49 #include "highscore.h"
50 #include "game/game.hpp"
51 #include "goal_base.h"
52 #include "story_base.h"
53 #include "toolbar_gui.h"
54 #include "framerate_type.h"
55 #include "screenshot_gui.h"
57 #include "league_gui.h"
58 #include "league_base.h"
59 #include "timer/timer.h"
60 #include "timer/timer_window.h"
61 #include "timer/timer_game_calendar.h"
64 #include "widgets/toolbar_widget.h"
66 #include "network/network.h"
67 #include "network/network_gui.h"
68 #include "network/network_func.h"
70 #include "safeguards.h"
73 /** Width of the toolbar, shared by statusbar. */
74 uint _toolbar_width
= 0;
76 RailType _last_built_railtype
;
77 RoadType _last_built_roadtype
;
78 RoadType _last_built_tramtype
;
87 /** Callback functions. */
88 enum CallBackFunction
{
94 static CallBackFunction _last_started_action
= CBF_NONE
; ///< Last started user action.
97 * Company name list item, with company-colour icon, name, and lock components.
99 class DropDownListCompanyItem
: public DropDownIcon
<DropDownIcon
<DropDownString
<DropDownListItem
>, true>> {
101 DropDownListCompanyItem(CompanyID company
, bool shaded
) : DropDownIcon
<DropDownIcon
<DropDownString
<DropDownListItem
>, true>>(SPR_COMPANY_ICON
, COMPANY_SPRITE_COLOUR(company
), NetworkCanJoinCompany(company
) ? SPR_EMPTY
: SPR_LOCK
, PAL_NONE
, STR_NULL
, company
, false, shaded
)
103 SetDParam(0, company
);
104 SetDParam(1, company
);
105 this->SetString(GetString(STR_COMPANY_NAME_COMPANY_NUM
));
110 * Pop up a generic text only menu.
112 * @param widget Toolbar button
113 * @param list List of items
114 * @param def Default item
116 static void PopupMainToolbarMenu(Window
*w
, WidgetID widget
, DropDownList
&&list
, int def
)
118 ShowDropDownList(w
, std::move(list
), def
, widget
, 0, true);
119 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
123 * Pop up a generic text only menu.
125 * @param widget Toolbar button
126 * @param strings List of strings for each item in the menu
128 static void PopupMainToolbarMenu(Window
*w
, WidgetID widget
, const std::initializer_list
<StringID
> &strings
)
132 for (StringID string
: strings
) {
133 if (string
== STR_NULL
) {
134 list
.push_back(MakeDropDownListDividerItem());
136 list
.push_back(MakeDropDownListStringItem(string
, i
));
140 PopupMainToolbarMenu(w
, widget
, std::move(list
), 0);
143 /** Enum for the Company Toolbar's network related buttons */
144 static const int CTMN_CLIENT_LIST
= -1; ///< Show the client list
145 static const int CTMN_SPECTATE
= -2; ///< Become spectator
146 static const int CTMN_SPECTATOR
= -3; ///< Show a company window as spectator
149 * Pop up a generic company list menu.
150 * @param w The toolbar window.
151 * @param widget The button widget id.
152 * @param grey A bitmask of which companies to mark as disabled.
154 static void PopupMainCompanyToolbMenu(Window
*w
, WidgetID widget
, CompanyMask grey
= 0)
159 case WID_TN_COMPANIES
:
160 if (!_networking
) break;
162 /* Add the client list button for the companies menu */
163 list
.push_back(MakeDropDownListStringItem(STR_NETWORK_COMPANY_LIST_CLIENT_LIST
, CTMN_CLIENT_LIST
));
165 if (_local_company
!= COMPANY_SPECTATOR
) {
166 list
.push_back(MakeDropDownListStringItem(STR_NETWORK_COMPANY_LIST_SPECTATE
, CTMN_SPECTATE
));
170 list
.push_back(MakeDropDownListStringItem(STR_STORY_BOOK_SPECTATOR
, CTMN_SPECTATOR
));
174 list
.push_back(MakeDropDownListStringItem(STR_GOALS_SPECTATOR
, CTMN_SPECTATOR
));
178 for (CompanyID c
= COMPANY_FIRST
; c
< MAX_COMPANIES
; c
++) {
179 if (!Company::IsValidID(c
)) continue;
180 list
.push_back(std::make_unique
<DropDownListCompanyItem
>(c
, HasBit(grey
, c
)));
183 PopupMainToolbarMenu(w
, widget
, std::move(list
), _local_company
== COMPANY_SPECTATOR
? (widget
== WID_TN_COMPANIES
? CTMN_CLIENT_LIST
: CTMN_SPECTATOR
) : (int)_local_company
);
186 static ToolbarMode _toolbar_mode
;
188 static CallBackFunction
SelectSignTool()
190 if (_last_started_action
== CBF_PLACE_SIGN
) {
191 ResetObjectToPlace();
194 SetObjectToPlace(SPR_CURSOR_SIGN
, PAL_NONE
, HT_RECT
, WC_MAIN_TOOLBAR
, 0);
195 return CBF_PLACE_SIGN
;
199 /* --- Pausing --- */
201 static CallBackFunction
ToolbarPauseClick(Window
*)
203 if (_networking
&& !_network_server
) return CBF_NONE
; // only server can pause the game
205 if (Command
<CMD_PAUSE
>::Post(PM_PAUSED_NORMAL
, _pause_mode
== PM_UNPAUSED
)) {
206 if (_settings_client
.sound
.confirm
) SndPlayFx(SND_15_BEEP
);
212 * Toggle fast forward mode.
216 static CallBackFunction
ToolbarFastForwardClick(Window
*)
218 if (_networking
) return CBF_NONE
; // no fast forward in network game
220 ChangeGameSpeed(_game_speed
== 100);
222 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
227 * Game Option button menu entries.
229 enum OptionMenuEntries
{
233 OME_GAMESCRIPT_SETTINGS
,
238 OME_SHOW_STATIONNAMES
,
239 OME_SHOW_WAYPOINTNAMES
,
241 OME_SHOW_COMPETITOR_SIGNS
,
244 OME_TRANSPARENTBUILDINGS
,
245 OME_SHOW_STATIONSIGNS
,
249 * Handle click on Options button in toolbar.
251 * @param w parent window the shown Drop down list is attached to.
254 static CallBackFunction
ToolbarOptionsClick(Window
*w
)
257 list
.push_back(MakeDropDownListStringItem(STR_SETTINGS_MENU_GAME_OPTIONS
, OME_GAMEOPTIONS
));
258 list
.push_back(MakeDropDownListStringItem(STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE
, OME_SETTINGS
));
259 /* Changes to the per-AI settings don't get send from the server to the clients. Clients get
260 * the settings once they join but never update it. As such don't show the window at all
261 * to network clients. */
262 if (!_networking
|| _network_server
) {
263 list
.push_back(MakeDropDownListStringItem(STR_SETTINGS_MENU_AI_SETTINGS
, OME_AI_SETTINGS
));
264 list
.push_back(MakeDropDownListStringItem(STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS
, OME_GAMESCRIPT_SETTINGS
));
266 list
.push_back(MakeDropDownListStringItem(STR_SETTINGS_MENU_NEWGRF_SETTINGS
, OME_NEWGRFSETTINGS
));
267 if (_game_mode
!= GM_EDITOR
&& !_networking
) {
268 list
.push_back(MakeDropDownListStringItem(STR_SETTINGS_MENU_SANDBOX_OPTIONS
, OME_SANDBOX
));
270 list
.push_back(MakeDropDownListStringItem(STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS
, OME_TRANSPARENCIES
));
271 list
.push_back(MakeDropDownListDividerItem());
272 list
.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt
, DO_SHOW_TOWN_NAMES
), STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED
, OME_SHOW_TOWNNAMES
));
273 list
.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt
, DO_SHOW_STATION_NAMES
), STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED
, OME_SHOW_STATIONNAMES
));
274 list
.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt
, DO_SHOW_WAYPOINT_NAMES
), STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED
, OME_SHOW_WAYPOINTNAMES
));
275 list
.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt
, DO_SHOW_SIGNS
), STR_SETTINGS_MENU_SIGNS_DISPLAYED
, OME_SHOW_SIGNS
));
276 list
.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt
, DO_SHOW_COMPETITOR_SIGNS
), STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS
, OME_SHOW_COMPETITOR_SIGNS
));
277 list
.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt
, DO_FULL_ANIMATION
), STR_SETTINGS_MENU_FULL_ANIMATION
, OME_FULL_ANIMATION
));
278 list
.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt
, DO_FULL_DETAIL
), STR_SETTINGS_MENU_FULL_DETAIL
, OME_FULL_DETAILS
));
279 list
.push_back(MakeDropDownListCheckedItem(IsTransparencySet(TO_HOUSES
), STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS
, OME_TRANSPARENTBUILDINGS
));
280 list
.push_back(MakeDropDownListCheckedItem(IsTransparencySet(TO_SIGNS
), STR_SETTINGS_MENU_TRANSPARENT_SIGNS
, OME_SHOW_STATIONSIGNS
));
282 ShowDropDownList(w
, std::move(list
), 0, WID_TN_SETTINGS
, 140, true);
283 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
288 * Handle click on one of the entries in the Options button menu.
290 * @param index Index being clicked.
293 static CallBackFunction
MenuClickSettings(int index
)
296 case OME_GAMEOPTIONS
: ShowGameOptions(); return CBF_NONE
;
297 case OME_SETTINGS
: ShowGameSettings(); return CBF_NONE
;
298 case OME_AI_SETTINGS
: ShowAIConfigWindow(); return CBF_NONE
;
299 case OME_GAMESCRIPT_SETTINGS
: ShowGSConfigWindow(); return CBF_NONE
;
300 case OME_NEWGRFSETTINGS
: ShowNewGRFSettings(!_networking
&& _settings_client
.gui
.UserIsAllowedToChangeNewGRFs(), true, true, &_grfconfig
); return CBF_NONE
;
301 case OME_SANDBOX
: ShowCheatWindow(); break;
302 case OME_TRANSPARENCIES
: ShowTransparencyToolbar(); break;
304 case OME_SHOW_TOWNNAMES
: ToggleBit(_display_opt
, DO_SHOW_TOWN_NAMES
); break;
305 case OME_SHOW_STATIONNAMES
: ToggleBit(_display_opt
, DO_SHOW_STATION_NAMES
); break;
306 case OME_SHOW_WAYPOINTNAMES
: ToggleBit(_display_opt
, DO_SHOW_WAYPOINT_NAMES
); break;
307 case OME_SHOW_SIGNS
: ToggleBit(_display_opt
, DO_SHOW_SIGNS
); break;
308 case OME_SHOW_COMPETITOR_SIGNS
:
309 ToggleBit(_display_opt
, DO_SHOW_COMPETITOR_SIGNS
);
310 InvalidateWindowClassesData(WC_SIGN_LIST
, -1);
312 case OME_FULL_ANIMATION
: ToggleBit(_display_opt
, DO_FULL_ANIMATION
); CheckBlitter(); break;
313 case OME_FULL_DETAILS
: ToggleBit(_display_opt
, DO_FULL_DETAIL
); break;
314 case OME_TRANSPARENTBUILDINGS
: ToggleTransparency(TO_HOUSES
); break;
315 case OME_SHOW_STATIONSIGNS
: ToggleTransparency(TO_SIGNS
); break;
317 MarkWholeScreenDirty();
322 * SaveLoad entries in scenario editor mode.
324 enum SaveLoadEditorMenuEntries
{
325 SLEME_SAVE_SCENARIO
= 0,
327 SLEME_SAVE_HEIGHTMAP
,
328 SLEME_LOAD_HEIGHTMAP
,
334 * SaveLoad entries in normal game mode.
336 enum SaveLoadNormalMenuEntries
{
344 * Handle click on Save button in toolbar in normal game mode.
346 * @param w parent window the shown save dialogue is attached to.
349 static CallBackFunction
ToolbarSaveClick(Window
*w
)
351 PopupMainToolbarMenu(w
, WID_TN_SAVE
, {STR_FILE_MENU_SAVE_GAME
, STR_FILE_MENU_LOAD_GAME
, STR_FILE_MENU_QUIT_GAME
,
352 STR_NULL
, STR_FILE_MENU_EXIT
});
357 * Handle click on SaveLoad button in toolbar in the scenario editor.
359 * @param w parent window the shown save dialogue is attached to.
362 static CallBackFunction
ToolbarScenSaveOrLoad(Window
*w
)
364 PopupMainToolbarMenu(w
, WID_TE_SAVE
, {STR_SCENEDIT_FILE_MENU_SAVE_SCENARIO
, STR_SCENEDIT_FILE_MENU_LOAD_SCENARIO
,
365 STR_SCENEDIT_FILE_MENU_SAVE_HEIGHTMAP
, STR_SCENEDIT_FILE_MENU_LOAD_HEIGHTMAP
,
366 STR_SCENEDIT_FILE_MENU_QUIT_EDITOR
, STR_NULL
, STR_SCENEDIT_FILE_MENU_QUIT
});
371 * Handle click on one of the entries in the SaveLoad menu.
373 * @param index Index being clicked.
376 static CallBackFunction
MenuClickSaveLoad(int index
= 0)
378 if (_game_mode
== GM_EDITOR
) {
380 case SLEME_SAVE_SCENARIO
: ShowSaveLoadDialog(FT_SCENARIO
, SLO_SAVE
); break;
381 case SLEME_LOAD_SCENARIO
: ShowSaveLoadDialog(FT_SCENARIO
, SLO_LOAD
); break;
382 case SLEME_SAVE_HEIGHTMAP
: ShowSaveLoadDialog(FT_HEIGHTMAP
, SLO_SAVE
); break;
383 case SLEME_LOAD_HEIGHTMAP
: ShowSaveLoadDialog(FT_HEIGHTMAP
, SLO_LOAD
); break;
384 case SLEME_EXIT_TOINTRO
: AskExitToGameMenu(); break;
385 case SLEME_EXIT_GAME
: HandleExitGameRequest(); break;
389 case SLNME_SAVE_GAME
: ShowSaveLoadDialog(FT_SAVEGAME
, SLO_SAVE
); break;
390 case SLNME_LOAD_GAME
: ShowSaveLoadDialog(FT_SAVEGAME
, SLO_LOAD
); break;
391 case SLNME_EXIT_TOINTRO
: AskExitToGameMenu(); break;
392 case SLNME_EXIT_GAME
: HandleExitGameRequest(); break;
398 /* --- Map button menu --- */
400 enum MapMenuEntries
{
401 MME_SHOW_SMALLMAP
= 0,
402 MME_SHOW_EXTRAVIEWPORTS
,
405 MME_SHOW_TOWNDIRECTORY
,
406 MME_SHOW_INDUSTRYDIRECTORY
,
409 static CallBackFunction
ToolbarMapClick(Window
*w
)
412 list
.push_back(MakeDropDownListStringItem(STR_MAP_MENU_MAP_OF_WORLD
, MME_SHOW_SMALLMAP
));
413 list
.push_back(MakeDropDownListStringItem(STR_MAP_MENU_EXTRA_VIEWPORT
, MME_SHOW_EXTRAVIEWPORTS
));
414 list
.push_back(MakeDropDownListStringItem(STR_MAP_MENU_LINGRAPH_LEGEND
, MME_SHOW_LINKGRAPH
));
415 list
.push_back(MakeDropDownListStringItem(STR_MAP_MENU_SIGN_LIST
, MME_SHOW_SIGNLISTS
));
416 PopupMainToolbarMenu(w
, WID_TN_SMALL_MAP
, std::move(list
), 0);
420 static CallBackFunction
ToolbarScenMapTownDir(Window
*w
)
423 list
.push_back(MakeDropDownListStringItem(STR_MAP_MENU_MAP_OF_WORLD
, MME_SHOW_SMALLMAP
));
424 list
.push_back(MakeDropDownListStringItem(STR_MAP_MENU_EXTRA_VIEWPORT
, MME_SHOW_EXTRAVIEWPORTS
));
425 list
.push_back(MakeDropDownListStringItem(STR_MAP_MENU_SIGN_LIST
, MME_SHOW_SIGNLISTS
));
426 list
.push_back(MakeDropDownListStringItem(STR_TOWN_MENU_TOWN_DIRECTORY
, MME_SHOW_TOWNDIRECTORY
));
427 list
.push_back(MakeDropDownListStringItem(STR_INDUSTRY_MENU_INDUSTRY_DIRECTORY
, MME_SHOW_INDUSTRYDIRECTORY
));
428 PopupMainToolbarMenu(w
, WID_TE_SMALL_MAP
, std::move(list
), 0);
433 * Handle click on one of the entries in the Map menu.
435 * @param index Index being clicked.
438 static CallBackFunction
MenuClickMap(int index
)
441 case MME_SHOW_SMALLMAP
: ShowSmallMap(); break;
442 case MME_SHOW_EXTRAVIEWPORTS
: ShowExtraViewportWindow(); break;
443 case MME_SHOW_LINKGRAPH
: ShowLinkGraphLegend(); break;
444 case MME_SHOW_SIGNLISTS
: ShowSignList(); break;
445 case MME_SHOW_TOWNDIRECTORY
: ShowTownDirectory(); break;
446 case MME_SHOW_INDUSTRYDIRECTORY
: ShowIndustryDirectory(); break;
451 /* --- Town button menu --- */
453 static CallBackFunction
ToolbarTownClick(Window
*w
)
455 if (_settings_game
.economy
.found_town
== TF_FORBIDDEN
) {
456 PopupMainToolbarMenu(w
, WID_TN_TOWNS
, {STR_TOWN_MENU_TOWN_DIRECTORY
});
458 PopupMainToolbarMenu(w
, WID_TN_TOWNS
, {STR_TOWN_MENU_TOWN_DIRECTORY
, STR_TOWN_MENU_FOUND_TOWN
});
464 * Handle click on one of the entries in the Town menu.
466 * @param index Index being clicked.
469 static CallBackFunction
MenuClickTown(int index
)
472 case 0: ShowTownDirectory(); break;
473 case 1: // setting could be changed when the dropdown was open
474 if (_settings_game
.economy
.found_town
!= TF_FORBIDDEN
) ShowFoundTownWindow();
480 /* --- Subidies button menu --- */
482 static CallBackFunction
ToolbarSubsidiesClick(Window
*w
)
484 PopupMainToolbarMenu(w
, WID_TN_SUBSIDIES
, {STR_SUBSIDIES_MENU_SUBSIDIES
});
489 * Handle click on the entry in the Subsidies menu.
493 static CallBackFunction
MenuClickSubsidies(int)
499 /* --- Stations button menu --- */
501 static CallBackFunction
ToolbarStationsClick(Window
*w
)
503 PopupMainCompanyToolbMenu(w
, WID_TN_STATIONS
);
508 * Handle click on the entry in the Stations menu
510 * @param index CompanyID to show station list for
513 static CallBackFunction
MenuClickStations(int index
)
515 ShowCompanyStations((CompanyID
)index
);
519 /* --- Finances button menu --- */
521 static CallBackFunction
ToolbarFinancesClick(Window
*w
)
523 PopupMainCompanyToolbMenu(w
, WID_TN_FINANCES
);
528 * Handle click on the entry in the finances overview menu.
530 * @param index CompanyID to show finances for.
533 static CallBackFunction
MenuClickFinances(int index
)
535 ShowCompanyFinances((CompanyID
)index
);
539 /* --- Company's button menu --- */
541 static CallBackFunction
ToolbarCompaniesClick(Window
*w
)
543 PopupMainCompanyToolbMenu(w
, WID_TN_COMPANIES
, 0);
548 * Handle click on the entry in the Company menu.
550 * @param index Menu entry to handle.
553 static CallBackFunction
MenuClickCompany(int index
)
557 case CTMN_CLIENT_LIST
:
562 if (_network_server
) {
563 NetworkServerDoMove(CLIENT_ID_SERVER
, COMPANY_SPECTATOR
);
564 MarkWholeScreenDirty();
566 NetworkClientRequestMove(COMPANY_SPECTATOR
);
571 ShowCompany((CompanyID
)index
);
575 /* --- Story button menu --- */
577 static CallBackFunction
ToolbarStoryClick(Window
*w
)
579 PopupMainCompanyToolbMenu(w
, WID_TN_STORY
, 0);
584 * Handle click on the entry in the Story menu
586 * @param index CompanyID to show story book for
589 static CallBackFunction
MenuClickStory(int index
)
591 ShowStoryBook(index
== CTMN_SPECTATOR
? INVALID_COMPANY
: (CompanyID
)index
);
595 /* --- Goal button menu --- */
597 static CallBackFunction
ToolbarGoalClick(Window
*w
)
599 PopupMainCompanyToolbMenu(w
, WID_TN_GOAL
, 0);
604 * Handle click on the entry in the Goal menu
606 * @param index CompanyID to show story book for
609 static CallBackFunction
MenuClickGoal(int index
)
611 ShowGoalsList(index
== CTMN_SPECTATOR
? INVALID_COMPANY
: (CompanyID
)index
);
615 /* --- Graphs and League Table button menu --- */
618 * Enum for the League Toolbar's and Graph Toolbar's related buttons.
619 * Use continuous numbering as League Toolbar can be combined into the Graph Toolbar.
621 static const int GRMN_OPERATING_PROFIT_GRAPH
= -1; ///< Show operating profit graph
622 static const int GRMN_INCOME_GRAPH
= -2; ///< Show income graph
623 static const int GRMN_DELIVERED_CARGO_GRAPH
= -3; ///< Show delivered cargo graph
624 static const int GRMN_PERFORMANCE_HISTORY_GRAPH
= -4; ///< Show performance history graph
625 static const int GRMN_COMPANY_VALUE_GRAPH
= -5; ///< Show company value graph
626 static const int GRMN_CARGO_PAYMENT_RATES
= -6; ///< Show cargo payment rates graph
627 static const int LTMN_PERFORMANCE_LEAGUE
= -7; ///< Show default league table
628 static const int LTMN_PERFORMANCE_RATING
= -8; ///< Show detailed performance rating
629 static const int LTMN_HIGHSCORE
= -9; ///< Show highscrore table
631 static void AddDropDownLeagueTableOptions(DropDownList
&list
)
633 if (LeagueTable::GetNumItems() > 0) {
634 for (LeagueTable
*lt
: LeagueTable::Iterate()) {
635 list
.push_back(MakeDropDownListStringItem(lt
->title
, lt
->index
));
638 list
.push_back(MakeDropDownListStringItem(STR_GRAPH_MENU_COMPANY_LEAGUE_TABLE
, LTMN_PERFORMANCE_LEAGUE
));
639 list
.push_back(MakeDropDownListStringItem(STR_GRAPH_MENU_DETAILED_PERFORMANCE_RATING
, LTMN_PERFORMANCE_RATING
));
641 list
.push_back(MakeDropDownListStringItem(STR_GRAPH_MENU_HIGHSCORE
, LTMN_HIGHSCORE
));
646 static CallBackFunction
ToolbarGraphsClick(Window
*w
)
650 list
.push_back(MakeDropDownListStringItem(STR_GRAPH_MENU_OPERATING_PROFIT_GRAPH
, GRMN_OPERATING_PROFIT_GRAPH
));
651 list
.push_back(MakeDropDownListStringItem(STR_GRAPH_MENU_INCOME_GRAPH
, GRMN_INCOME_GRAPH
));
652 list
.push_back(MakeDropDownListStringItem(STR_GRAPH_MENU_DELIVERED_CARGO_GRAPH
, GRMN_DELIVERED_CARGO_GRAPH
));
653 list
.push_back(MakeDropDownListStringItem(STR_GRAPH_MENU_PERFORMANCE_HISTORY_GRAPH
, GRMN_PERFORMANCE_HISTORY_GRAPH
));
654 list
.push_back(MakeDropDownListStringItem(STR_GRAPH_MENU_COMPANY_VALUE_GRAPH
, GRMN_COMPANY_VALUE_GRAPH
));
655 list
.push_back(MakeDropDownListStringItem(STR_GRAPH_MENU_CARGO_PAYMENT_RATES
, GRMN_CARGO_PAYMENT_RATES
));
657 if (_toolbar_mode
!= TB_NORMAL
) AddDropDownLeagueTableOptions(list
);
659 ShowDropDownList(w
, std::move(list
), GRMN_OPERATING_PROFIT_GRAPH
, WID_TN_GRAPHS
, 140, true);
660 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
665 static CallBackFunction
ToolbarLeagueClick(Window
*w
)
669 AddDropDownLeagueTableOptions(list
);
671 int selected
= list
[0]->result
;
672 ShowDropDownList(w
, std::move(list
), selected
, WID_TN_LEAGUE
, 140, true);
673 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
679 * Handle click on the entry in the Graphs or CompanyLeague.
681 * @param index Graph to show.
684 static CallBackFunction
MenuClickGraphsOrLeague(int index
)
687 case GRMN_OPERATING_PROFIT_GRAPH
: ShowOperatingProfitGraph(); break;
688 case GRMN_INCOME_GRAPH
: ShowIncomeGraph(); break;
689 case GRMN_DELIVERED_CARGO_GRAPH
: ShowDeliveredCargoGraph(); break;
690 case GRMN_PERFORMANCE_HISTORY_GRAPH
: ShowPerformanceHistoryGraph(); break;
691 case GRMN_COMPANY_VALUE_GRAPH
: ShowCompanyValueGraph(); break;
692 case GRMN_CARGO_PAYMENT_RATES
: ShowCargoPaymentRates(); break;
693 case LTMN_PERFORMANCE_LEAGUE
: ShowPerformanceLeagueTable(); break;
694 case LTMN_PERFORMANCE_RATING
: ShowPerformanceRatingDetail(); break;
695 case LTMN_HIGHSCORE
: ShowHighscoreTable(); break;
697 if (LeagueTable::IsValidID(index
)) {
698 ShowScriptLeagueTable((LeagueTableID
)index
);
707 /* --- Industries button menu --- */
709 static CallBackFunction
ToolbarIndustryClick(Window
*w
)
711 /* Disable build-industry menu if we are a spectator */
712 if (_local_company
== COMPANY_SPECTATOR
) {
713 PopupMainToolbarMenu(w
, WID_TN_INDUSTRIES
, {STR_INDUSTRY_MENU_INDUSTRY_DIRECTORY
, STR_INDUSTRY_MENU_INDUSTRY_CHAIN
});
715 PopupMainToolbarMenu(w
, WID_TN_INDUSTRIES
, {STR_INDUSTRY_MENU_INDUSTRY_DIRECTORY
, STR_INDUSTRY_MENU_INDUSTRY_CHAIN
, STR_INDUSTRY_MENU_FUND_NEW_INDUSTRY
});
721 * Handle click on the entry in the Industry menu.
723 * @param index Menu entry number.
726 static CallBackFunction
MenuClickIndustry(int index
)
729 case 0: ShowIndustryDirectory(); break;
730 case 1: ShowIndustryCargoesWindow(); break;
731 case 2: ShowBuildIndustryWindow(); break;
736 /* --- Trains button menu + 1 helper function for all vehicles. --- */
738 static void ToolbarVehicleClick(Window
*w
, VehicleType veh
)
742 for (const Company
*c
: Company::Iterate()) {
743 if (c
->group_all
[veh
].num_vehicle
== 0) SetBit(dis
, c
->index
);
745 PopupMainCompanyToolbMenu(w
, WID_TN_VEHICLE_START
+ veh
, dis
);
749 static CallBackFunction
ToolbarTrainClick(Window
*w
)
751 ToolbarVehicleClick(w
, VEH_TRAIN
);
756 * Handle click on the entry in the Train menu.
758 * @param index CompanyID to show train list for.
761 static CallBackFunction
MenuClickShowTrains(int index
)
763 ShowVehicleListWindow((CompanyID
)index
, VEH_TRAIN
);
767 /* --- Road vehicle button menu --- */
769 static CallBackFunction
ToolbarRoadClick(Window
*w
)
771 ToolbarVehicleClick(w
, VEH_ROAD
);
776 * Handle click on the entry in the Road Vehicles menu.
778 * @param index CompanyID to show road vehicles list for.
781 static CallBackFunction
MenuClickShowRoad(int index
)
783 ShowVehicleListWindow((CompanyID
)index
, VEH_ROAD
);
787 /* --- Ship button menu --- */
789 static CallBackFunction
ToolbarShipClick(Window
*w
)
791 ToolbarVehicleClick(w
, VEH_SHIP
);
796 * Handle click on the entry in the Ships menu.
798 * @param index CompanyID to show ship list for.
801 static CallBackFunction
MenuClickShowShips(int index
)
803 ShowVehicleListWindow((CompanyID
)index
, VEH_SHIP
);
807 /* --- Aircraft button menu --- */
809 static CallBackFunction
ToolbarAirClick(Window
*w
)
811 ToolbarVehicleClick(w
, VEH_AIRCRAFT
);
816 * Handle click on the entry in the Aircraft menu.
818 * @param index CompanyID to show aircraft list for.
821 static CallBackFunction
MenuClickShowAir(int index
)
823 ShowVehicleListWindow((CompanyID
)index
, VEH_AIRCRAFT
);
827 /* --- Zoom in button --- */
829 static CallBackFunction
ToolbarZoomInClick(Window
*w
)
831 if (DoZoomInOutWindow(ZOOM_IN
, GetMainWindow())) {
832 w
->HandleButtonClick((_game_mode
== GM_EDITOR
) ? (WidgetID
)WID_TE_ZOOM_IN
: (WidgetID
)WID_TN_ZOOM_IN
);
833 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
838 /* --- Zoom out button --- */
840 static CallBackFunction
ToolbarZoomOutClick(Window
*w
)
842 if (DoZoomInOutWindow(ZOOM_OUT
, GetMainWindow())) {
843 w
->HandleButtonClick((_game_mode
== GM_EDITOR
) ? (WidgetID
)WID_TE_ZOOM_OUT
: (WidgetID
)WID_TN_ZOOM_OUT
);
844 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
849 /* --- Rail button menu --- */
851 static CallBackFunction
ToolbarBuildRailClick(Window
*w
)
853 ShowDropDownList(w
, GetRailTypeDropDownList(), _last_built_railtype
, WID_TN_RAILS
, 140, true);
854 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
859 * Handle click on the entry in the Build Rail menu.
861 * @param index RailType to show the build toolbar for.
864 static CallBackFunction
MenuClickBuildRail(int index
)
866 _last_built_railtype
= (RailType
)index
;
867 ShowBuildRailToolbar(_last_built_railtype
);
871 /* --- Road button menu --- */
873 static CallBackFunction
ToolbarBuildRoadClick(Window
*w
)
875 ShowDropDownList(w
, GetRoadTypeDropDownList(RTTB_ROAD
), _last_built_roadtype
, WID_TN_ROADS
, 140, true);
876 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
881 * Handle click on the entry in the Build Road menu.
883 * @param index RoadType to show the build toolbar for.
886 static CallBackFunction
MenuClickBuildRoad(int index
)
888 _last_built_roadtype
= (RoadType
)index
;
889 ShowBuildRoadToolbar(_last_built_roadtype
);
893 /* --- Tram button menu --- */
895 static CallBackFunction
ToolbarBuildTramClick(Window
*w
)
897 ShowDropDownList(w
, GetRoadTypeDropDownList(RTTB_TRAM
), _last_built_tramtype
, WID_TN_TRAMS
, 140, true);
898 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
903 * Handle click on the entry in the Build Tram menu.
905 * @param index RoadType to show the build toolbar for.
908 static CallBackFunction
MenuClickBuildTram(int index
)
910 _last_built_tramtype
= (RoadType
)index
;
911 ShowBuildRoadToolbar(_last_built_tramtype
);
915 /* --- Water button menu --- */
917 static CallBackFunction
ToolbarBuildWaterClick(Window
*w
)
920 list
.push_back(MakeDropDownListIconItem(SPR_IMG_BUILD_CANAL
, PAL_NONE
, STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION
, 0));
921 ShowDropDownList(w
, std::move(list
), 0, WID_TN_WATER
, 140, true);
922 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
927 * Handle click on the entry in the Build Waterways menu.
931 static CallBackFunction
MenuClickBuildWater(int)
933 ShowBuildDocksToolbar();
937 /* --- Airport button menu --- */
939 static CallBackFunction
ToolbarBuildAirClick(Window
*w
)
942 list
.push_back(MakeDropDownListIconItem(SPR_IMG_AIRPORT
, PAL_NONE
, STR_AIRCRAFT_MENU_AIRPORT_CONSTRUCTION
, 0));
943 ShowDropDownList(w
, std::move(list
), 0, WID_TN_AIR
, 140, true);
944 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
949 * Handle click on the entry in the Build Air menu.
953 static CallBackFunction
MenuClickBuildAir(int)
955 ShowBuildAirToolbar();
959 /* --- Forest button menu --- */
961 static CallBackFunction
ToolbarForestClick(Window
*w
)
964 list
.push_back(MakeDropDownListIconItem(SPR_IMG_LANDSCAPING
, PAL_NONE
, STR_LANDSCAPING_MENU_LANDSCAPING
, 0));
965 list
.push_back(MakeDropDownListIconItem(SPR_IMG_PLANTTREES
, PAL_NONE
, STR_LANDSCAPING_MENU_PLANT_TREES
, 1));
966 list
.push_back(MakeDropDownListIconItem(SPR_IMG_SIGN
, PAL_NONE
, STR_LANDSCAPING_MENU_PLACE_SIGN
, 2));
967 ShowDropDownList(w
, std::move(list
), 0, WID_TN_LANDSCAPE
, 100, true);
968 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
973 * Handle click on the entry in the landscaping menu.
975 * @param index Menu entry clicked.
978 static CallBackFunction
MenuClickForest(int index
)
981 case 0: ShowTerraformToolbar(); break;
982 case 1: ShowBuildTreesToolbar(); break;
983 case 2: return SelectSignTool();
988 /* --- Music button menu --- */
990 static CallBackFunction
ToolbarMusicClick(Window
*w
)
992 PopupMainToolbarMenu(w
, _game_mode
== GM_EDITOR
? (WidgetID
)WID_TE_MUSIC_SOUND
: (WidgetID
)WID_TN_MUSIC_SOUND
, {STR_TOOLBAR_SOUND_MUSIC
});
997 * Handle click on the entry in the Music menu.
1001 static CallBackFunction
MenuClickMusicWindow(int)
1007 /* --- Newspaper button menu --- */
1009 static CallBackFunction
ToolbarNewspaperClick(Window
*w
)
1011 PopupMainToolbarMenu(w
, WID_TN_MESSAGES
, {STR_NEWS_MENU_LAST_MESSAGE_NEWS_REPORT
, STR_NEWS_MENU_MESSAGE_HISTORY_MENU
, STR_NEWS_MENU_DELETE_ALL_MESSAGES
});
1016 * Handle click on the entry in the Newspaper menu.
1018 * @param index Menu entry clicked.
1021 static CallBackFunction
MenuClickNewspaper(int index
)
1024 case 0: ShowLastNewsMessage(); break;
1025 case 1: ShowMessageHistory(); break;
1026 case 2: DeleteAllMessages(); break;
1031 /* --- Help button menu --- */
1033 static CallBackFunction
PlaceLandBlockInfo()
1035 if (_last_started_action
== CBF_PLACE_LANDINFO
) {
1036 ResetObjectToPlace();
1039 SetObjectToPlace(SPR_CURSOR_QUERY
, PAL_NONE
, HT_RECT
, WC_MAIN_TOOLBAR
, 0);
1040 return CBF_PLACE_LANDINFO
;
1044 static CallBackFunction
ToolbarHelpClick(Window
*w
)
1046 if (_settings_client
.gui
.newgrf_developer_tools
) {
1047 PopupMainToolbarMenu(w
, _game_mode
== GM_EDITOR
? (WidgetID
)WID_TE_HELP
: (WidgetID
)WID_TN_HELP
, {STR_ABOUT_MENU_LAND_BLOCK_INFO
,
1048 STR_ABOUT_MENU_HELP
, STR_NULL
, STR_ABOUT_MENU_TOGGLE_CONSOLE
, STR_ABOUT_MENU_AI_DEBUG
,
1049 STR_ABOUT_MENU_SCREENSHOT
, STR_ABOUT_MENU_SHOW_FRAMERATE
, STR_ABOUT_MENU_ABOUT_OPENTTD
,
1050 STR_ABOUT_MENU_SPRITE_ALIGNER
, STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES
, STR_ABOUT_MENU_TOGGLE_DIRTY_BLOCKS
,
1051 STR_ABOUT_MENU_TOGGLE_WIDGET_OUTLINES
});
1053 PopupMainToolbarMenu(w
, _game_mode
== GM_EDITOR
? (WidgetID
)WID_TE_HELP
: (WidgetID
)WID_TN_HELP
, {STR_ABOUT_MENU_LAND_BLOCK_INFO
,
1054 STR_ABOUT_MENU_HELP
, STR_NULL
, STR_ABOUT_MENU_TOGGLE_CONSOLE
, STR_ABOUT_MENU_AI_DEBUG
,
1055 STR_ABOUT_MENU_SCREENSHOT
, STR_ABOUT_MENU_SHOW_FRAMERATE
, STR_ABOUT_MENU_ABOUT_OPENTTD
});
1061 * Toggle drawing of sprites' bounding boxes.
1062 * @note has only an effect when newgrf_developer_tools are active.
1064 * Function is found here and not in viewport.cpp in order to avoid
1065 * importing the settings structs to there.
1067 void ToggleBoundingBoxes()
1069 extern bool _draw_bounding_boxes
;
1070 /* Always allow to toggle them off */
1071 if (_settings_client
.gui
.newgrf_developer_tools
|| _draw_bounding_boxes
) {
1072 _draw_bounding_boxes
= !_draw_bounding_boxes
;
1073 MarkWholeScreenDirty();
1078 * Toggle drawing of the dirty blocks.
1079 * @note has only an effect when newgrf_developer_tools are active.
1081 * Function is found here and not in viewport.cpp in order to avoid
1082 * importing the settings structs to there.
1084 void ToggleDirtyBlocks()
1086 extern bool _draw_dirty_blocks
;
1087 /* Always allow to toggle them off */
1088 if (_settings_client
.gui
.newgrf_developer_tools
|| _draw_dirty_blocks
) {
1089 _draw_dirty_blocks
= !_draw_dirty_blocks
;
1090 MarkWholeScreenDirty();
1095 * Toggle drawing of widget outlihes.
1096 * @note has only an effect when newgrf_developer_tools are active.
1098 void ToggleWidgetOutlines()
1100 extern bool _draw_widget_outlines
;
1101 /* Always allow to toggle them off */
1102 if (_settings_client
.gui
.newgrf_developer_tools
|| _draw_widget_outlines
) {
1103 _draw_widget_outlines
= !_draw_widget_outlines
;
1104 MarkWholeScreenDirty();
1109 * Set the starting year for a scenario.
1110 * @param year New starting year.
1112 void SetStartingYear(TimerGameCalendar::Year year
)
1114 _settings_game
.game_creation
.starting_year
= Clamp(year
, CalendarTime::MIN_YEAR
, CalendarTime::MAX_YEAR
);
1115 TimerGameCalendar::Date new_calendar_date
= TimerGameCalendar::ConvertYMDToDate(_settings_game
.game_creation
.starting_year
, 0, 1);
1116 TimerGameEconomy::Date new_economy_date
= new_calendar_date
.base();
1118 /* We must set both Calendar and Economy dates to keep them in sync. Calendar first. */
1119 TimerGameCalendar::SetDate(new_calendar_date
, 0);
1121 /* If you open a savegame as a scenario, there may already be link graphs and/or vehicles. These use economy date. */
1122 LinkGraphSchedule::instance
.ShiftDates(new_economy_date
- TimerGameEconomy::date
);
1123 for (auto v
: Vehicle::Iterate()) v
->ShiftDates(new_economy_date
- TimerGameEconomy::date
);
1125 /* Only change the date after changing cached values above. */
1126 TimerGameEconomy::SetDate(new_economy_date
, 0);
1130 * Choose the proper callback function for the main toolbar's help menu.
1131 * @param index The menu index which was selected.
1134 static CallBackFunction
MenuClickHelp(int index
)
1137 case 0: return PlaceLandBlockInfo();
1138 case 1: ShowHelpWindow(); break;
1139 case 2: IConsoleSwitch(); break;
1140 case 3: ShowScriptDebugWindow(INVALID_COMPANY
, _ctrl_pressed
); break;
1141 case 4: ShowScreenshotWindow(); break;
1142 case 5: ShowFramerateWindow(); break;
1143 case 6: ShowAboutWindow(); break;
1144 case 7: ShowSpriteAlignerWindow(); break;
1145 case 8: ToggleBoundingBoxes(); break;
1146 case 9: ToggleDirtyBlocks(); break;
1147 case 10: ToggleWidgetOutlines(); break;
1152 /* --- Switch toolbar button --- */
1154 static CallBackFunction
ToolbarSwitchClick(Window
*w
)
1156 if (_toolbar_mode
!= TB_LOWER
) {
1157 _toolbar_mode
= TB_LOWER
;
1159 _toolbar_mode
= TB_UPPER
;
1163 w
->SetWidgetLoweredState(_game_mode
== GM_EDITOR
? (WidgetID
)WID_TE_SWITCH_BAR
: (WidgetID
)WID_TN_SWITCH_BAR
, _toolbar_mode
== TB_LOWER
);
1164 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
1168 /* --- Scenario editor specific handlers. */
1171 * Called when clicking at the date panel of the scenario editor toolbar.
1173 static CallBackFunction
ToolbarScenDatePanel(Window
*w
)
1175 SetDParam(0, _settings_game
.game_creation
.starting_year
);
1176 ShowQueryString(STR_JUST_INT
, STR_MAPGEN_START_DATE_QUERY_CAPT
, 8, w
, CS_NUMERAL
, QSF_ENABLE_DEFAULT
);
1180 static CallBackFunction
ToolbarScenDateBackward(Window
*w
)
1182 /* don't allow too fast scrolling */
1183 if (!(w
->flags
& WF_TIMEOUT
) || w
->timeout_timer
<= 1) {
1184 w
->HandleButtonClick(WID_TE_DATE_BACKWARD
);
1187 SetStartingYear(_settings_game
.game_creation
.starting_year
- 1);
1189 _left_button_clicked
= false;
1193 static CallBackFunction
ToolbarScenDateForward(Window
*w
)
1195 /* don't allow too fast scrolling */
1196 if (!(w
->flags
& WF_TIMEOUT
) || w
->timeout_timer
<= 1) {
1197 w
->HandleButtonClick(WID_TE_DATE_FORWARD
);
1200 SetStartingYear(_settings_game
.game_creation
.starting_year
+ 1);
1202 _left_button_clicked
= false;
1206 static CallBackFunction
ToolbarScenGenLand(Window
*w
)
1208 w
->HandleButtonClick(WID_TE_LAND_GENERATE
);
1209 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
1211 ShowEditorTerraformToolbar();
1215 static CallBackFunction
ToolbarScenGenTownClick(Window
*w
)
1217 PopupMainToolbarMenu(w
, WID_TE_TOWN_GENERATE
, {STR_SCENEDIT_TOWN_MENU_BUILD_TOWN
, STR_SCENEDIT_TOWN_MENU_PACE_HOUSE
});
1221 static CallBackFunction
ToolbarScenGenTown(int index
)
1224 case 0: ShowFoundTownWindow(); break;
1225 case 1: ShowBuildHousePicker(nullptr); break;
1230 static CallBackFunction
ToolbarScenGenIndustry(Window
*w
)
1232 w
->HandleButtonClick(WID_TE_INDUSTRY
);
1233 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
1234 ShowBuildIndustryWindow();
1238 static CallBackFunction
ToolbarScenBuildRoadClick(Window
*w
)
1240 ShowDropDownList(w
, GetScenRoadTypeDropDownList(RTTB_ROAD
), _last_built_roadtype
, WID_TE_ROADS
, 140, true);
1241 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
1246 * Handle click on the entry in the Build Road menu.
1248 * @param index RoadType to show the build toolbar for.
1251 static CallBackFunction
ToolbarScenBuildRoad(int index
)
1253 _last_built_roadtype
= (RoadType
)index
;
1254 ShowBuildRoadScenToolbar(_last_built_roadtype
);
1258 static CallBackFunction
ToolbarScenBuildTramClick(Window
*w
)
1260 ShowDropDownList(w
, GetScenRoadTypeDropDownList(RTTB_TRAM
), _last_built_tramtype
, WID_TE_TRAMS
, 140, true);
1261 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
1266 * Handle click on the entry in the Build Tram menu.
1268 * @param index RoadType to show the build toolbar for.
1271 static CallBackFunction
ToolbarScenBuildTram(int index
)
1273 _last_built_tramtype
= (RoadType
)index
;
1274 ShowBuildRoadScenToolbar(_last_built_tramtype
);
1278 static CallBackFunction
ToolbarScenBuildDocks(Window
*w
)
1280 w
->HandleButtonClick(WID_TE_WATER
);
1281 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
1282 ShowBuildDocksScenToolbar();
1286 static CallBackFunction
ToolbarScenPlantTrees(Window
*w
)
1288 w
->HandleButtonClick(WID_TE_TREES
);
1289 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
1290 ShowBuildTreesToolbar();
1294 static CallBackFunction
ToolbarScenPlaceSign(Window
*w
)
1296 w
->HandleButtonClick(WID_TE_SIGNS
);
1297 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
1298 return SelectSignTool();
1301 static CallBackFunction
ToolbarBtn_NULL(Window
*)
1306 typedef CallBackFunction
MenuClickedProc(int index
);
1308 static MenuClickedProc
* const _menu_clicked_procs
[] = {
1311 MenuClickSettings
, // 2
1312 MenuClickSaveLoad
, // 3
1315 MenuClickSubsidies
, // 6
1316 MenuClickStations
, // 7
1317 MenuClickFinances
, // 8
1318 MenuClickCompany
, // 9
1319 MenuClickStory
, // 10
1320 MenuClickGoal
, // 11
1321 MenuClickGraphsOrLeague
, // 12
1322 MenuClickGraphsOrLeague
, // 13
1323 MenuClickIndustry
, // 14
1324 MenuClickShowTrains
, // 15
1325 MenuClickShowRoad
, // 16
1326 MenuClickShowShips
, // 17
1327 MenuClickShowAir
, // 18
1330 MenuClickBuildRail
, // 21
1331 MenuClickBuildRoad
, // 22
1332 MenuClickBuildTram
, // 23
1333 MenuClickBuildWater
, // 24
1334 MenuClickBuildAir
, // 25
1335 MenuClickForest
, // 26
1336 MenuClickMusicWindow
, // 27
1337 MenuClickNewspaper
, // 28
1338 MenuClickHelp
, // 29
1341 /** Full blown container to make it behave exactly as we want :) */
1342 class NWidgetToolbarContainer
: public NWidgetContainer
{
1344 uint spacers
; ///< Number of spacer widgets in this toolbar
1347 NWidgetToolbarContainer() : NWidgetContainer(NWID_HORIZONTAL
)
1352 * Check whether the given widget type is a button for us.
1353 * @param type the widget type to check.
1354 * @return true if it is a button for us.
1356 bool IsButton(WidgetType type
) const
1358 return type
== WWT_IMGBTN
|| type
== WWT_IMGBTN_2
|| type
== WWT_PUSHIMGBTN
;
1361 void SetupSmallestSize(Window
*w
) override
1363 this->smallest_x
= 0; // Biggest child
1364 this->smallest_y
= 0; // Biggest child
1367 this->resize_x
= 1; // We only resize in this direction
1368 this->resize_y
= 0; // We never resize in this direction
1372 /* First initialise some variables... */
1373 for (const auto &child_wid
: this->children
) {
1374 child_wid
->SetupSmallestSize(w
);
1375 this->smallest_y
= std::max(this->smallest_y
, child_wid
->smallest_y
+ child_wid
->padding
.Vertical());
1376 if (this->IsButton(child_wid
->type
)) {
1378 this->smallest_x
= std::max(this->smallest_x
, child_wid
->smallest_x
+ child_wid
->padding
.Horizontal());
1379 } else if (child_wid
->type
== NWID_SPACER
) {
1384 /* ... then in a second pass make sure the 'current' heights are set. Won't change ever. */
1385 for (const auto &child_wid
: this->children
) {
1386 child_wid
->current_y
= this->smallest_y
;
1387 if (!this->IsButton(child_wid
->type
)) {
1388 child_wid
->current_x
= child_wid
->smallest_x
;
1391 _toolbar_width
= nbuttons
* this->smallest_x
;
1394 void AssignSizePosition(SizingType sizing
, int x
, int y
, uint given_width
, uint given_height
, bool rtl
) override
1396 assert(given_width
>= this->smallest_x
&& given_height
>= this->smallest_y
);
1400 this->current_x
= given_width
;
1401 this->current_y
= given_height
;
1403 /* Figure out what are the visible buttons */
1404 uint arrangable_count
, button_count
, spacer_count
;
1405 const WidgetID
*arrangement
= GetButtonArrangement(given_width
, arrangable_count
, button_count
, spacer_count
);
1407 /* Create us ourselves a quick lookup table from WidgetID to slot. */
1408 std::map
<WidgetID
, uint
> lookup
;
1409 for (auto it
= std::begin(this->children
); it
!= std::end(this->children
); ++it
) {
1410 NWidgetBase
*nwid
= it
->get();
1411 nwid
->current_x
= 0; /* Hide widget, it will be revealed in the next step. */
1412 if (nwid
->type
== NWID_SPACER
) continue;
1413 lookup
[dynamic_cast<NWidgetCore
*>(nwid
)->index
] = std::distance(this->children
.begin(), it
);
1416 /* Now assign the widgets to their rightful place */
1417 uint position
= 0; // Place to put next child relative to origin of the container.
1418 uint spacer_space
= std::max(0, (int)given_width
- (int)(button_count
* this->smallest_x
)); // Remaining spacing for 'spacer' widgets
1419 uint button_space
= given_width
- spacer_space
; // Remaining spacing for the buttons
1423 /* Index into the arrangement indices. */
1424 const WidgetID
*slotp
= rtl
? &arrangement
[arrangable_count
- 1] : arrangement
;
1425 for (uint i
= 0; i
< arrangable_count
; i
++) {
1426 uint slot
= lookup
[*slotp
];
1427 auto &child_wid
= this->children
[slot
];
1428 /* If we have space to give to the spacers, do that. */
1429 if (spacer_space
> 0 && slot
> 0 && slot
< this->children
.size() - 1) {
1430 const auto &possible_spacer
= this->children
[slot
+ (rtl
? 1 : -1)];
1431 if (possible_spacer
!= nullptr && possible_spacer
->type
== NWID_SPACER
) {
1432 uint add
= spacer_space
/ (spacer_count
- spacer_i
);
1434 spacer_space
-= add
;
1439 /* Buttons can be scaled, the others not. */
1440 if (this->IsButton(child_wid
->type
)) {
1441 child_wid
->current_x
= button_space
/ (button_count
- button_i
);
1442 button_space
-= child_wid
->current_x
;
1445 child_wid
->current_x
= child_wid
->smallest_x
;
1447 child_wid
->AssignSizePosition(sizing
, x
+ position
, y
, child_wid
->current_x
, this->current_y
, rtl
);
1448 position
+= child_wid
->current_x
;
1458 void Draw(const Window
*w
) override
1460 /* Draw brown-red toolbar bg. */
1461 const Rect r
= this->GetCurrentRect();
1462 GfxFillRect(r
, PC_VERY_DARK_RED
);
1463 GfxFillRect(r
, PC_DARK_RED
, FILLRECT_CHECKER
);
1465 this->NWidgetContainer::Draw(w
);
1469 * Get the arrangement of the buttons for the toolbar.
1470 * @param width the new width of the toolbar.
1471 * @param arrangable_count output of the number of visible items.
1472 * @param button_count output of the number of visible buttons.
1473 * @param spacer_count output of the number of spacers.
1474 * @return the button configuration.
1476 virtual const WidgetID
*GetButtonArrangement(uint
&width
, uint
&arrangable_count
, uint
&button_count
, uint
&spacer_count
) const = 0;
1479 /** Container for the 'normal' main toolbar */
1480 class NWidgetMainToolbarContainer
: public NWidgetToolbarContainer
{
1481 const WidgetID
*GetButtonArrangement(uint
&width
, uint
&arrangable_count
, uint
&button_count
, uint
&spacer_count
) const override
1483 static const uint SMALLEST_ARRANGEMENT
= 14;
1484 static const uint BIGGEST_ARRANGEMENT
= 20;
1486 /* The number of buttons of each row of the toolbar should match the number of items which we want to be visible.
1487 * The total number of buttons should be equal to arrangable_count * 2.
1488 * No bad things happen, but we could see strange behaviours if we have buttons < (arrangable_count * 2) like a
1489 * pause button appearing on the right of the lower toolbar and weird resizing of the widgets even if there is
1492 static const WidgetID arrange14
[] = {
1494 WID_TN_FAST_FORWARD
,
1523 static const WidgetID arrange15
[] = {
1525 WID_TN_FAST_FORWARD
,
1556 static const WidgetID arrange16
[] = {
1558 WID_TN_FAST_FORWARD
,
1575 WID_TN_FAST_FORWARD
,
1591 static const WidgetID arrange17
[] = {
1593 WID_TN_FAST_FORWARD
,
1611 WID_TN_FAST_FORWARD
,
1628 static const WidgetID arrange18
[] = {
1630 WID_TN_FAST_FORWARD
,
1649 WID_TN_FAST_FORWARD
,
1667 static const WidgetID arrange19
[] = {
1669 WID_TN_FAST_FORWARD
,
1689 WID_TN_FAST_FORWARD
,
1708 static const WidgetID arrange20
[] = {
1710 WID_TN_FAST_FORWARD
,
1731 WID_TN_FAST_FORWARD
,
1751 static const WidgetID arrange_all
[] = {
1753 WID_TN_FAST_FORWARD
,
1784 /* If at least BIGGEST_ARRANGEMENT fit, just spread all the buttons nicely */
1785 uint full_buttons
= std::max(CeilDiv(width
, this->smallest_x
), SMALLEST_ARRANGEMENT
);
1786 if (full_buttons
> BIGGEST_ARRANGEMENT
) {
1787 button_count
= arrangable_count
= lengthof(arrange_all
);
1788 spacer_count
= this->spacers
;
1792 /* Introduce the split toolbar */
1793 static const WidgetID
* const arrangements
[] = { arrange14
, arrange15
, arrange16
, arrange17
, arrange18
, arrange19
, arrange20
};
1795 button_count
= arrangable_count
= full_buttons
;
1796 spacer_count
= this->spacers
;
1797 return arrangements
[full_buttons
- SMALLEST_ARRANGEMENT
] + ((_toolbar_mode
== TB_LOWER
) ? full_buttons
: 0);
1801 /** Container for the scenario editor's toolbar */
1802 class NWidgetScenarioToolbarContainer
: public NWidgetToolbarContainer
{
1803 uint panel_widths
[2]; ///< The width of the two panels (the text panel and date panel)
1805 void SetupSmallestSize(Window
*w
) override
1807 this->NWidgetToolbarContainer::SetupSmallestSize(w
);
1809 /* Find the size of panel_widths */
1811 for (const auto &child_wid
: this->children
) {
1812 if (child_wid
->type
== NWID_SPACER
|| this->IsButton(child_wid
->type
)) continue;
1814 assert(i
< lengthof(this->panel_widths
));
1815 this->panel_widths
[i
++] = child_wid
->current_x
;
1816 _toolbar_width
+= child_wid
->current_x
;
1820 const WidgetID
*GetButtonArrangement(uint
&width
, uint
&arrangable_count
, uint
&button_count
, uint
&spacer_count
) const override
1822 static const WidgetID arrange_all
[] = {
1824 WID_TE_FAST_FORWARD
,
1832 WID_TE_LAND_GENERATE
,
1833 WID_TE_TOWN_GENERATE
,
1843 static const WidgetID arrange_nopanel
[] = {
1845 WID_TE_FAST_FORWARD
,
1852 WID_TE_LAND_GENERATE
,
1853 WID_TE_TOWN_GENERATE
,
1863 static const WidgetID arrange_switch
[] = {
1866 WID_TE_LAND_GENERATE
,
1867 WID_TE_TOWN_GENERATE
,
1877 WID_TE_FAST_FORWARD
,
1889 /* If we can place all buttons *and* the panels, show them. */
1890 uint min_full_width
= (lengthof(arrange_all
) - lengthof(this->panel_widths
)) * this->smallest_x
+ this->panel_widths
[0] + this->panel_widths
[1];
1891 if (width
>= min_full_width
) {
1892 width
-= this->panel_widths
[0] + this->panel_widths
[1];
1893 arrangable_count
= lengthof(arrange_all
);
1894 button_count
= arrangable_count
- 2;
1895 spacer_count
= this->spacers
;
1899 /* Otherwise don't show the date panel and if we can't fit half the buttons and the panels anymore, split the toolbar in two */
1900 uint min_small_width
= (lengthof(arrange_switch
) - lengthof(this->panel_widths
)) * this->smallest_x
/ 2 + this->panel_widths
[1];
1901 if (width
> min_small_width
) {
1902 width
-= this->panel_widths
[1];
1903 arrangable_count
= lengthof(arrange_nopanel
);
1904 button_count
= arrangable_count
- 1;
1905 spacer_count
= this->spacers
- 1;
1906 return arrange_nopanel
;
1910 width
-= this->panel_widths
[1];
1911 arrangable_count
= lengthof(arrange_switch
) / 2;
1912 button_count
= arrangable_count
- 1;
1914 return arrange_switch
+ ((_toolbar_mode
== TB_LOWER
) ? arrangable_count
: 0);
1918 /* --- Toolbar handling for the 'normal' case */
1920 typedef CallBackFunction
ToolbarButtonProc(Window
*w
);
1922 static ToolbarButtonProc
* const _toolbar_button_procs
[] = {
1924 ToolbarFastForwardClick
,
1925 ToolbarOptionsClick
,
1929 ToolbarSubsidiesClick
,
1930 ToolbarStationsClick
,
1931 ToolbarFinancesClick
,
1932 ToolbarCompaniesClick
,
1937 ToolbarIndustryClick
,
1943 ToolbarZoomOutClick
,
1944 ToolbarBuildRailClick
,
1945 ToolbarBuildRoadClick
,
1946 ToolbarBuildTramClick
,
1947 ToolbarBuildWaterClick
,
1948 ToolbarBuildAirClick
,
1951 ToolbarNewspaperClick
,
1956 /** Main toolbar. */
1957 struct MainToolbarWindow
: Window
{
1958 MainToolbarWindow(WindowDesc
&desc
) : Window(desc
)
1960 this->InitNested(0);
1962 _last_started_action
= CBF_NONE
;
1963 CLRBITS(this->flags
, WF_WHITE_BORDER
);
1964 this->SetWidgetDisabledState(WID_TN_PAUSE
, _networking
&& !_network_server
); // if not server, disable pause button
1965 this->SetWidgetDisabledState(WID_TN_FAST_FORWARD
, _networking
); // if networking, disable fast-forward button
1966 PositionMainToolbar(this);
1967 DoZoomInOutWindow(ZOOM_NONE
, this);
1970 void FindWindowPlacementAndResize([[maybe_unused
]] int def_width
, [[maybe_unused
]] int def_height
) override
1972 Window::FindWindowPlacementAndResize(_toolbar_width
, def_height
);
1975 void OnPaint() override
1977 /* If spectator, disable all construction buttons
1978 * ie : Build road, rail, ships, airports and landscaping
1979 * Since enabled state is the default, just disable when needed */
1980 this->SetWidgetsDisabledState(_local_company
== COMPANY_SPECTATOR
, WID_TN_RAILS
, WID_TN_ROADS
, WID_TN_TRAMS
, WID_TN_WATER
, WID_TN_AIR
, WID_TN_LANDSCAPE
);
1981 /* disable company list drop downs, if there are no companies */
1982 this->SetWidgetsDisabledState(Company::GetNumItems() == 0, WID_TN_STATIONS
, WID_TN_FINANCES
, WID_TN_TRAINS
, WID_TN_ROADVEHS
, WID_TN_SHIPS
, WID_TN_AIRCRAFT
);
1984 this->SetWidgetDisabledState(WID_TN_GOAL
, Goal::GetNumItems() == 0);
1985 this->SetWidgetDisabledState(WID_TN_STORY
, StoryPage::GetNumItems() == 0);
1987 this->DrawWidgets();
1990 void OnClick([[maybe_unused
]] Point pt
, WidgetID widget
, [[maybe_unused
]] int click_count
) override
1992 if (_game_mode
!= GM_MENU
&& !this->IsWidgetDisabled(widget
)) _toolbar_button_procs
[widget
](this);
1995 void OnDropdownSelect(WidgetID widget
, int index
) override
1997 CallBackFunction cbf
= _menu_clicked_procs
[widget
](index
);
1998 if (cbf
!= CBF_NONE
) _last_started_action
= cbf
;
2001 EventState
OnHotkey(int hotkey
) override
2003 CallBackFunction cbf
= CBF_NONE
;
2005 case MTHK_PAUSE
: ToolbarPauseClick(this); break;
2006 case MTHK_FASTFORWARD
: ToolbarFastForwardClick(this); break;
2007 case MTHK_SETTINGS
: ShowGameOptions(); break;
2008 case MTHK_SAVEGAME
: MenuClickSaveLoad(); break;
2009 case MTHK_LOADGAME
: ShowSaveLoadDialog(FT_SAVEGAME
, SLO_LOAD
); break;
2010 case MTHK_SMALLMAP
: ShowSmallMap(); break;
2011 case MTHK_TOWNDIRECTORY
: ShowTownDirectory(); break;
2012 case MTHK_SUBSIDIES
: ShowSubsidiesList(); break;
2013 case MTHK_STATIONS
: ShowCompanyStations(_local_company
); break;
2014 case MTHK_FINANCES
: ShowCompanyFinances(_local_company
); break;
2015 case MTHK_COMPANIES
: ShowCompany(_local_company
); break;
2016 case MTHK_STORY
: ShowStoryBook(_local_company
); break;
2017 case MTHK_GOAL
: ShowGoalsList(_local_company
); break;
2018 case MTHK_GRAPHS
: ShowOperatingProfitGraph(); break;
2019 case MTHK_LEAGUE
: ShowFirstLeagueTable(); break;
2020 case MTHK_INDUSTRIES
: ShowBuildIndustryWindow(); break;
2021 case MTHK_TRAIN_LIST
: ShowVehicleListWindow(_local_company
, VEH_TRAIN
); break;
2022 case MTHK_ROADVEH_LIST
: ShowVehicleListWindow(_local_company
, VEH_ROAD
); break;
2023 case MTHK_SHIP_LIST
: ShowVehicleListWindow(_local_company
, VEH_SHIP
); break;
2024 case MTHK_AIRCRAFT_LIST
: ShowVehicleListWindow(_local_company
, VEH_AIRCRAFT
); break;
2025 case MTHK_ZOOM_IN
: ToolbarZoomInClick(this); break;
2026 case MTHK_ZOOM_OUT
: ToolbarZoomOutClick(this); break;
2027 case MTHK_BUILD_RAIL
: ShowBuildRailToolbar(_last_built_railtype
); break;
2028 case MTHK_BUILD_ROAD
: ShowBuildRoadToolbar(_last_built_roadtype
); break;
2029 case MTHK_BUILD_TRAM
: ShowBuildRoadToolbar(_last_built_tramtype
); break;
2030 case MTHK_BUILD_DOCKS
: ShowBuildDocksToolbar(); break;
2031 case MTHK_BUILD_AIRPORT
: ShowBuildAirToolbar(); break;
2032 case MTHK_BUILD_TREES
: ShowBuildTreesToolbar(); break;
2033 case MTHK_MUSIC
: ShowMusicWindow(); break;
2034 case MTHK_SCRIPT_DEBUG
: ShowScriptDebugWindow(); break;
2035 case MTHK_SMALL_SCREENSHOT
: MakeScreenshotWithConfirm(SC_VIEWPORT
); break;
2036 case MTHK_ZOOMEDIN_SCREENSHOT
: MakeScreenshotWithConfirm(SC_ZOOMEDIN
); break;
2037 case MTHK_DEFAULTZOOM_SCREENSHOT
: MakeScreenshotWithConfirm(SC_DEFAULTZOOM
); break;
2038 case MTHK_GIANT_SCREENSHOT
: MakeScreenshotWithConfirm(SC_WORLD
); break;
2039 case MTHK_CHEATS
: if (!_networking
) ShowCheatWindow(); break;
2040 case MTHK_TERRAFORM
: ShowTerraformToolbar(); break;
2041 case MTHK_EXTRA_VIEWPORT
: ShowExtraViewportWindowForTileUnderCursor(); break;
2042 case MTHK_CLIENT_LIST
: if (_networking
) ShowClientList(); break;
2043 case MTHK_SIGN_LIST
: ShowSignList(); break;
2044 case MTHK_LANDINFO
: cbf
= PlaceLandBlockInfo(); break;
2045 default: return ES_NOT_HANDLED
;
2047 if (cbf
!= CBF_NONE
) _last_started_action
= cbf
;
2051 void OnPlaceObject([[maybe_unused
]] Point pt
, TileIndex tile
) override
2053 switch (_last_started_action
) {
2054 case CBF_PLACE_SIGN
:
2055 PlaceProc_Sign(tile
);
2058 case CBF_PLACE_LANDINFO
:
2062 default: NOT_REACHED();
2066 void OnPlaceObjectAbort() override
2068 _last_started_action
= CBF_NONE
;
2071 /** Refresh the state of pause / game-speed on a regular interval.*/
2072 IntervalTimer
<TimerWindow
> refresh_interval
= {std::chrono::milliseconds(30), [this](auto) {
2073 if (this->IsWidgetLowered(WID_TN_PAUSE
) != !!_pause_mode
) {
2074 this->ToggleWidgetLoweredState(WID_TN_PAUSE
);
2075 this->SetWidgetDirty(WID_TN_PAUSE
);
2078 if (this->IsWidgetLowered(WID_TN_FAST_FORWARD
) != (_game_speed
!= 100)) {
2079 this->ToggleWidgetLoweredState(WID_TN_FAST_FORWARD
);
2080 this->SetWidgetDirty(WID_TN_FAST_FORWARD
);
2084 void OnTimeout() override
2086 /* We do not want to automatically raise the pause, fast forward and
2087 * switchbar buttons; they have to stay down when pressed etc. */
2088 for (WidgetID i
= WID_TN_SETTINGS
; i
< WID_TN_SWITCH_BAR
; i
++) {
2089 this->RaiseWidgetWhenLowered(i
);
2094 * Some data on this window has become invalid.
2095 * @param data Information about the changed data.
2096 * @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.
2098 void OnInvalidateData([[maybe_unused
]] int data
= 0, [[maybe_unused
]] bool gui_scope
= true) override
2100 if (!gui_scope
) return;
2101 HandleZoomMessage(this, GetMainWindow()->viewport
, WID_TN_ZOOM_IN
, WID_TN_ZOOM_OUT
);
2104 static inline HotkeyList hotkeys
{"maintoolbar", {
2105 Hotkey({WKC_F1
, WKC_PAUSE
}, "pause", MTHK_PAUSE
),
2106 Hotkey(0, "fastforward", MTHK_FASTFORWARD
),
2107 Hotkey(WKC_F2
, "settings", MTHK_SETTINGS
),
2108 Hotkey(WKC_F3
, "saveload", MTHK_SAVEGAME
),
2109 Hotkey(0, "load_game", MTHK_LOADGAME
),
2110 Hotkey({WKC_F4
, 'M'}, "smallmap", MTHK_SMALLMAP
),
2111 Hotkey(WKC_F5
, "town_list", MTHK_TOWNDIRECTORY
),
2112 Hotkey(WKC_F6
, "subsidies", MTHK_SUBSIDIES
),
2113 Hotkey(WKC_F7
, "station_list", MTHK_STATIONS
),
2114 Hotkey(WKC_F8
, "finances", MTHK_FINANCES
),
2115 Hotkey(WKC_F9
, "companies", MTHK_COMPANIES
),
2116 Hotkey(0, "story_book", MTHK_STORY
),
2117 Hotkey(0, "goal_list", MTHK_GOAL
),
2118 Hotkey(WKC_F10
, "graphs", MTHK_GRAPHS
),
2119 Hotkey(WKC_F11
, "league", MTHK_LEAGUE
),
2120 Hotkey(WKC_F12
, "industry_list", MTHK_INDUSTRIES
),
2121 Hotkey(WKC_SHIFT
| WKC_F1
, "train_list", MTHK_TRAIN_LIST
),
2122 Hotkey(WKC_SHIFT
| WKC_F2
, "roadveh_list", MTHK_ROADVEH_LIST
),
2123 Hotkey(WKC_SHIFT
| WKC_F3
, "ship_list", MTHK_SHIP_LIST
),
2124 Hotkey(WKC_SHIFT
| WKC_F4
, "aircraft_list", MTHK_AIRCRAFT_LIST
),
2125 Hotkey({WKC_NUM_PLUS
, WKC_EQUALS
, WKC_SHIFT
| WKC_EQUALS
, WKC_SHIFT
| WKC_F5
}, "zoomin", MTHK_ZOOM_IN
),
2126 Hotkey({WKC_NUM_MINUS
, WKC_MINUS
, WKC_SHIFT
| WKC_MINUS
, WKC_SHIFT
| WKC_F6
}, "zoomout", MTHK_ZOOM_OUT
),
2127 Hotkey(WKC_SHIFT
| WKC_F7
, "build_rail", MTHK_BUILD_RAIL
),
2128 Hotkey(WKC_SHIFT
| WKC_F8
, "build_road", MTHK_BUILD_ROAD
),
2129 Hotkey(0, "build_tram", MTHK_BUILD_TRAM
),
2130 Hotkey(WKC_SHIFT
| WKC_F9
, "build_docks", MTHK_BUILD_DOCKS
),
2131 Hotkey(WKC_SHIFT
| WKC_F10
, "build_airport", MTHK_BUILD_AIRPORT
),
2132 Hotkey(WKC_SHIFT
| WKC_F11
, "build_trees", MTHK_BUILD_TREES
),
2133 Hotkey(WKC_SHIFT
| WKC_F12
, "music", MTHK_MUSIC
),
2134 Hotkey(0, "ai_debug", MTHK_SCRIPT_DEBUG
),
2135 Hotkey(WKC_CTRL
| 'S', "small_screenshot", MTHK_SMALL_SCREENSHOT
),
2136 Hotkey(WKC_CTRL
| 'P', "zoomedin_screenshot", MTHK_ZOOMEDIN_SCREENSHOT
),
2137 Hotkey(WKC_CTRL
| 'D', "defaultzoom_screenshot", MTHK_DEFAULTZOOM_SCREENSHOT
),
2138 Hotkey(0, "giant_screenshot", MTHK_GIANT_SCREENSHOT
),
2139 Hotkey(WKC_CTRL
| WKC_ALT
| 'C', "cheats", MTHK_CHEATS
),
2140 Hotkey('L', "terraform", MTHK_TERRAFORM
),
2141 Hotkey('V', "extra_viewport", MTHK_EXTRA_VIEWPORT
),
2142 Hotkey(0, "client_list", MTHK_CLIENT_LIST
),
2143 Hotkey(0, "sign_list", MTHK_SIGN_LIST
),
2144 Hotkey(0, "land_info", MTHK_LANDINFO
),
2148 static std::unique_ptr
<NWidgetBase
> MakeMainToolbar()
2150 /** Sprites to use for the different toolbar buttons */
2151 static const SpriteID toolbar_button_sprites
[] = {
2152 SPR_IMG_PAUSE
, // WID_TN_PAUSE
2153 SPR_IMG_FASTFORWARD
, // WID_TN_FAST_FORWARD
2154 SPR_IMG_SETTINGS
, // WID_TN_SETTINGS
2155 SPR_IMG_SAVE
, // WID_TN_SAVE
2156 SPR_IMG_SMALLMAP
, // WID_TN_SMALL_MAP
2157 SPR_IMG_TOWN
, // WID_TN_TOWNS
2158 SPR_IMG_SUBSIDIES
, // WID_TN_SUBSIDIES
2159 SPR_IMG_COMPANY_LIST
, // WID_TN_STATIONS
2160 SPR_IMG_COMPANY_FINANCE
, // WID_TN_FINANCES
2161 SPR_IMG_COMPANY_GENERAL
, // WID_TN_COMPANIES
2162 SPR_IMG_STORY_BOOK
, // WID_TN_STORY
2163 SPR_IMG_GOAL
, // WID_TN_GOAL
2164 SPR_IMG_GRAPHS
, // WID_TN_GRAPHS
2165 SPR_IMG_COMPANY_LEAGUE
, // WID_TN_LEAGUE
2166 SPR_IMG_INDUSTRY
, // WID_TN_INDUSTRIES
2167 SPR_IMG_TRAINLIST
, // WID_TN_TRAINS
2168 SPR_IMG_TRUCKLIST
, // WID_TN_ROADVEHS
2169 SPR_IMG_SHIPLIST
, // WID_TN_SHIPS
2170 SPR_IMG_AIRPLANESLIST
, // WID_TN_AIRCRAFT
2171 SPR_IMG_ZOOMIN
, // WID_TN_ZOOMIN
2172 SPR_IMG_ZOOMOUT
, // WID_TN_ZOOMOUT
2173 SPR_IMG_BUILDRAIL
, // WID_TN_RAILS
2174 SPR_IMG_BUILDROAD
, // WID_TN_ROADS
2175 SPR_IMG_BUILDTRAMS
, // WID_TN_TRAMS
2176 SPR_IMG_BUILDWATER
, // WID_TN_WATER
2177 SPR_IMG_BUILDAIR
, // WID_TN_AIR
2178 SPR_IMG_LANDSCAPING
, // WID_TN_LANDSCAPE
2179 SPR_IMG_MUSIC
, // WID_TN_MUSIC_SOUND
2180 SPR_IMG_MESSAGES
, // WID_TN_MESSAGES
2181 SPR_IMG_QUERY
, // WID_TN_HELP
2182 SPR_IMG_SWITCH_TOOLBAR
, // WID_TN_SWITCH_BAR
2185 auto hor
= std::make_unique
<NWidgetMainToolbarContainer
>();
2186 for (WidgetID i
= 0; i
< WID_TN_END
; i
++) {
2188 case WID_TN_SMALL_MAP
:
2189 case WID_TN_FINANCES
:
2190 case WID_TN_VEHICLE_START
:
2191 case WID_TN_ZOOM_IN
:
2192 case WID_TN_BUILDING_TOOLS_START
:
2193 case WID_TN_MUSIC_SOUND
:
2194 hor
->Add(std::make_unique
<NWidgetSpacer
>(0, 0));
2197 auto leaf
= std::make_unique
<NWidgetLeaf
>(i
== WID_TN_SAVE
? WWT_IMGBTN_2
: WWT_IMGBTN
, COLOUR_GREY
, i
, toolbar_button_sprites
[i
], STR_TOOLBAR_TOOLTIP_PAUSE_GAME
+ i
);
2198 leaf
->SetMinimalSize(20, 20);
2199 hor
->Add(std::move(leaf
));
2205 static constexpr NWidgetPart _nested_toolbar_normal_widgets
[] = {
2206 NWidgetFunction(MakeMainToolbar
),
2209 static WindowDesc
_toolb_normal_desc(
2210 WDP_MANUAL
, nullptr, 0, 0,
2211 WC_MAIN_TOOLBAR
, WC_NONE
,
2212 WDF_NO_FOCUS
| WDF_NO_CLOSE
,
2213 _nested_toolbar_normal_widgets
,
2214 &MainToolbarWindow::hotkeys
2218 /* --- Toolbar handling for the scenario editor */
2220 static MenuClickedProc
* const _scen_toolbar_dropdown_procs
[] = {
2223 MenuClickSettings
, // 2
2224 MenuClickSaveLoad
, // 3
2233 ToolbarScenGenTown
, // 12
2235 ToolbarScenBuildRoad
, // 14
2236 ToolbarScenBuildTram
, // 15
2241 MenuClickMusicWindow
, // 20
2242 MenuClickHelp
, // 21
2246 static ToolbarButtonProc
* const _scen_toolbar_button_procs
[] = {
2248 ToolbarFastForwardClick
,
2249 ToolbarOptionsClick
,
2250 ToolbarScenSaveOrLoad
,
2252 ToolbarScenDatePanel
,
2253 ToolbarScenDateBackward
,
2254 ToolbarScenDateForward
,
2255 ToolbarScenMapTownDir
,
2257 ToolbarZoomOutClick
,
2259 ToolbarScenGenTownClick
,
2260 ToolbarScenGenIndustry
,
2261 ToolbarScenBuildRoadClick
,
2262 ToolbarScenBuildTramClick
,
2263 ToolbarScenBuildDocks
,
2264 ToolbarScenPlantTrees
,
2265 ToolbarScenPlaceSign
,
2272 enum MainToolbarEditorHotkeys
{
2287 MTEHK_SMALL_SCREENSHOT
,
2288 MTEHK_ZOOMEDIN_SCREENSHOT
,
2289 MTEHK_DEFAULTZOOM_SCREENSHOT
,
2290 MTEHK_GIANT_SCREENSHOT
,
2295 MTEHK_EXTRA_VIEWPORT
,
2298 struct ScenarioEditorToolbarWindow
: Window
{
2299 ScenarioEditorToolbarWindow(WindowDesc
&desc
) : Window(desc
)
2301 this->InitNested(0);
2303 _last_started_action
= CBF_NONE
;
2304 CLRBITS(this->flags
, WF_WHITE_BORDER
);
2305 PositionMainToolbar(this);
2306 DoZoomInOutWindow(ZOOM_NONE
, this);
2309 void FindWindowPlacementAndResize([[maybe_unused
]] int def_width
, [[maybe_unused
]] int def_height
) override
2311 Window::FindWindowPlacementAndResize(_toolbar_width
, def_height
);
2314 void OnPaint() override
2316 this->SetWidgetDisabledState(WID_TE_DATE_BACKWARD
, _settings_game
.game_creation
.starting_year
<= CalendarTime::MIN_YEAR
);
2317 this->SetWidgetDisabledState(WID_TE_DATE_FORWARD
, _settings_game
.game_creation
.starting_year
>= CalendarTime::MAX_YEAR
);
2318 this->SetWidgetDisabledState(WID_TE_ROADS
, (GetRoadTypes(true) & ~_roadtypes_type
) == ROADTYPES_NONE
);
2319 this->SetWidgetDisabledState(WID_TE_TRAMS
, (GetRoadTypes(true) & _roadtypes_type
) == ROADTYPES_NONE
);
2321 this->DrawWidgets();
2324 void SetStringParameters(WidgetID widget
) const override
2328 SetDParam(0, TimerGameCalendar::ConvertYMDToDate(_settings_game
.game_creation
.starting_year
, 0, 1));
2333 void DrawWidget(const Rect
&r
, WidgetID widget
) const override
2336 case WID_TE_SPACER
: {
2337 int height
= r
.Height();
2338 if (height
> 2 * GetCharacterHeight(FS_NORMAL
)) {
2339 DrawString(r
.left
, r
.right
, height
/ 2 - GetCharacterHeight(FS_NORMAL
), STR_SCENEDIT_TOOLBAR_OPENTTD
, TC_FROMSTRING
, SA_HOR_CENTER
);
2340 DrawString(r
.left
, r
.right
, height
/ 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR
, TC_FROMSTRING
, SA_HOR_CENTER
);
2342 DrawString(r
.left
, r
.right
, (height
- GetCharacterHeight(FS_NORMAL
)) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR
, TC_FROMSTRING
, SA_HOR_CENTER
);
2349 void UpdateWidgetSize(WidgetID widget
, Dimension
&size
, [[maybe_unused
]] const Dimension
&padding
, [[maybe_unused
]] Dimension
&fill
, [[maybe_unused
]] Dimension
&resize
) override
2353 size
.width
= std::max(GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_OPENTTD
).width
, GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR
).width
) + padding
.width
;
2357 SetDParam(0, TimerGameCalendar::ConvertYMDToDate(CalendarTime::MAX_YEAR
, 0, 1));
2358 size
= GetStringBoundingBox(STR_JUST_DATE_LONG
);
2363 void OnClick([[maybe_unused
]] Point pt
, WidgetID widget
, [[maybe_unused
]] int click_count
) override
2365 if (_game_mode
== GM_MENU
) return;
2366 CallBackFunction cbf
= _scen_toolbar_button_procs
[widget
](this);
2367 if (cbf
!= CBF_NONE
) _last_started_action
= cbf
;
2370 void OnDropdownSelect(WidgetID widget
, int index
) override
2372 CallBackFunction cbf
= _scen_toolbar_dropdown_procs
[widget
](index
);
2373 if (cbf
!= CBF_NONE
) _last_started_action
= cbf
;
2374 if (_settings_client
.sound
.click_beep
) SndPlayFx(SND_15_BEEP
);
2377 EventState
OnHotkey(int hotkey
) override
2379 CallBackFunction cbf
= CBF_NONE
;
2381 case MTEHK_PAUSE
: ToolbarPauseClick(this); break;
2382 case MTEHK_FASTFORWARD
: ToolbarFastForwardClick(this); break;
2383 case MTEHK_SETTINGS
: ShowGameOptions(); break;
2384 case MTEHK_SAVEGAME
: MenuClickSaveLoad(); break;
2385 case MTEHK_GENLAND
: ToolbarScenGenLand(this); break;
2386 case MTEHK_GENTOWN
: ToolbarScenGenTownClick(this); break;
2387 case MTEHK_GENINDUSTRY
: ToolbarScenGenIndustry(this); break;
2388 case MTEHK_BUILD_ROAD
: ToolbarScenBuildRoadClick(this); break;
2389 case MTEHK_BUILD_TRAM
: ToolbarScenBuildTramClick(this); break;
2390 case MTEHK_BUILD_DOCKS
: ToolbarScenBuildDocks(this); break;
2391 case MTEHK_BUILD_TREES
: ToolbarScenPlantTrees(this); break;
2392 case MTEHK_SIGN
: cbf
= ToolbarScenPlaceSign(this); break;
2393 case MTEHK_MUSIC
: ShowMusicWindow(); break;
2394 case MTEHK_LANDINFO
: cbf
= PlaceLandBlockInfo(); break;
2395 case MTEHK_SMALL_SCREENSHOT
: MakeScreenshotWithConfirm(SC_VIEWPORT
); break;
2396 case MTEHK_ZOOMEDIN_SCREENSHOT
: MakeScreenshotWithConfirm(SC_ZOOMEDIN
); break;
2397 case MTEHK_DEFAULTZOOM_SCREENSHOT
: MakeScreenshotWithConfirm(SC_DEFAULTZOOM
); break;
2398 case MTEHK_GIANT_SCREENSHOT
: MakeScreenshotWithConfirm(SC_WORLD
); break;
2399 case MTEHK_ZOOM_IN
: ToolbarZoomInClick(this); break;
2400 case MTEHK_ZOOM_OUT
: ToolbarZoomOutClick(this); break;
2401 case MTEHK_TERRAFORM
: ShowEditorTerraformToolbar(); break;
2402 case MTEHK_SMALLMAP
: ShowSmallMap(); break;
2403 case MTEHK_EXTRA_VIEWPORT
: ShowExtraViewportWindowForTileUnderCursor(); break;
2404 default: return ES_NOT_HANDLED
;
2406 if (cbf
!= CBF_NONE
) _last_started_action
= cbf
;
2410 void OnPlaceObject([[maybe_unused
]] Point pt
, TileIndex tile
) override
2412 switch (_last_started_action
) {
2413 case CBF_PLACE_SIGN
:
2414 PlaceProc_Sign(tile
);
2417 case CBF_PLACE_LANDINFO
:
2421 default: NOT_REACHED();
2425 void OnPlaceObjectAbort() override
2427 _last_started_action
= CBF_NONE
;
2430 void OnTimeout() override
2432 this->SetWidgetsLoweredState(false, WID_TE_DATE_BACKWARD
, WID_TE_DATE_FORWARD
);
2433 this->SetWidgetDirty(WID_TE_DATE_BACKWARD
);
2434 this->SetWidgetDirty(WID_TE_DATE_FORWARD
);
2437 /** Refresh the state of pause / game-speed on a regular interval.*/
2438 IntervalTimer
<TimerWindow
> refresh_interval
= {std::chrono::milliseconds(30), [this](auto) {
2439 if (this->IsWidgetLowered(WID_TE_PAUSE
) != !!_pause_mode
) {
2440 this->ToggleWidgetLoweredState(WID_TE_PAUSE
);
2444 if (this->IsWidgetLowered(WID_TE_FAST_FORWARD
) != (_game_speed
!= 100)) {
2445 this->ToggleWidgetLoweredState(WID_TE_FAST_FORWARD
);
2451 * Some data on this window has become invalid.
2452 * @param data Information about the changed data.
2453 * @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.
2455 void OnInvalidateData([[maybe_unused
]] int data
= 0, [[maybe_unused
]] bool gui_scope
= true) override
2457 if (!gui_scope
) return;
2458 HandleZoomMessage(this, GetMainWindow()->viewport
, WID_TE_ZOOM_IN
, WID_TE_ZOOM_OUT
);
2461 void OnQueryTextFinished(std::optional
<std::string
> str
) override
2463 /* Was 'cancel' pressed? */
2464 if (!str
.has_value()) return;
2466 TimerGameCalendar::Year value
;
2467 if (!str
->empty()) {
2468 value
= atoi(str
->c_str());
2470 /* An empty string means revert to the default */
2471 value
= CalendarTime::DEF_START_YEAR
.base();
2473 SetStartingYear(value
);
2478 static inline HotkeyList hotkeys
{"scenedit_maintoolbar", {
2479 Hotkey({WKC_F1
, WKC_PAUSE
}, "pause", MTEHK_PAUSE
),
2480 Hotkey(0, "fastforward", MTEHK_FASTFORWARD
),
2481 Hotkey(WKC_F2
, "settings", MTEHK_SETTINGS
),
2482 Hotkey(WKC_F3
, "saveload", MTEHK_SAVEGAME
),
2483 Hotkey(WKC_F4
, "gen_land", MTEHK_GENLAND
),
2484 Hotkey(WKC_F5
, "gen_town", MTEHK_GENTOWN
),
2485 Hotkey(WKC_F6
, "gen_industry", MTEHK_GENINDUSTRY
),
2486 Hotkey(WKC_F7
, "build_road", MTEHK_BUILD_ROAD
),
2487 Hotkey(0, "build_tram", MTEHK_BUILD_TRAM
),
2488 Hotkey(WKC_F8
, "build_docks", MTEHK_BUILD_DOCKS
),
2489 Hotkey(WKC_F9
, "build_trees", MTEHK_BUILD_TREES
),
2490 Hotkey(WKC_F10
, "build_sign", MTEHK_SIGN
),
2491 Hotkey(WKC_F11
, "music", MTEHK_MUSIC
),
2492 Hotkey(WKC_F12
, "land_info", MTEHK_LANDINFO
),
2493 Hotkey(WKC_CTRL
| 'S', "small_screenshot", MTEHK_SMALL_SCREENSHOT
),
2494 Hotkey(WKC_CTRL
| 'P', "zoomedin_screenshot", MTEHK_ZOOMEDIN_SCREENSHOT
),
2495 Hotkey(WKC_CTRL
| 'D', "defaultzoom_screenshot", MTEHK_DEFAULTZOOM_SCREENSHOT
),
2496 Hotkey(0, "giant_screenshot", MTEHK_GIANT_SCREENSHOT
),
2497 Hotkey({WKC_NUM_PLUS
, WKC_EQUALS
, WKC_SHIFT
| WKC_EQUALS
, WKC_SHIFT
| WKC_F5
}, "zoomin", MTEHK_ZOOM_IN
),
2498 Hotkey({WKC_NUM_MINUS
, WKC_MINUS
, WKC_SHIFT
| WKC_MINUS
, WKC_SHIFT
| WKC_F6
}, "zoomout", MTEHK_ZOOM_OUT
),
2499 Hotkey('L', "terraform", MTEHK_TERRAFORM
),
2500 Hotkey('M', "smallmap", MTEHK_SMALLMAP
),
2501 Hotkey('V', "extra_viewport", MTEHK_EXTRA_VIEWPORT
),
2505 static constexpr NWidgetPart _nested_toolb_scen_inner_widgets
[] = {
2506 NWidget(WWT_IMGBTN
, COLOUR_GREY
, WID_TE_PAUSE
), SetDataTip(SPR_IMG_PAUSE
, STR_TOOLBAR_TOOLTIP_PAUSE_GAME
),
2507 NWidget(WWT_IMGBTN
, COLOUR_GREY
, WID_TE_FAST_FORWARD
), SetDataTip(SPR_IMG_FASTFORWARD
, STR_TOOLBAR_TOOLTIP_FORWARD
),
2508 NWidget(WWT_IMGBTN
, COLOUR_GREY
, WID_TE_SETTINGS
), SetDataTip(SPR_IMG_SETTINGS
, STR_TOOLBAR_TOOLTIP_OPTIONS
),
2509 NWidget(WWT_IMGBTN_2
, COLOUR_GREY
, WID_TE_SAVE
), SetDataTip(SPR_IMG_SAVE
, STR_SCENEDIT_TOOLBAR_TOOLTIP_SAVE_SCENARIO_LOAD_SCENARIO
),
2510 NWidget(NWID_SPACER
),
2511 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_TE_SPACER
), EndContainer(),
2512 NWidget(NWID_SPACER
),
2513 NWidget(WWT_PANEL
, COLOUR_GREY
, WID_TE_DATE_PANEL
),
2514 NWidget(NWID_HORIZONTAL
), SetPIP(2, 2, 2), SetPadding(1),
2515 NWidget(WWT_IMGBTN
, COLOUR_GREY
, WID_TE_DATE_BACKWARD
), SetDataTip(SPR_ARROW_DOWN
, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD
), SetFill(0, 1),
2516 NWidget(WWT_TEXT
, COLOUR_GREY
, WID_TE_DATE
), SetDataTip(STR_JUST_DATE_LONG
, STR_SCENEDIT_TOOLBAR_TOOLTIP_SET_DATE
), SetTextStyle(TC_WHITE
), SetAlignment(SA_CENTER
), SetFill(0, 1),
2517 NWidget(WWT_IMGBTN
, COLOUR_GREY
, WID_TE_DATE_FORWARD
), SetDataTip(SPR_ARROW_UP
, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD
), SetFill(0, 1),
2520 NWidget(NWID_SPACER
),
2521 NWidget(WWT_IMGBTN
, COLOUR_GREY
, WID_TE_SMALL_MAP
), SetDataTip(SPR_IMG_SMALLMAP
, STR_SCENEDIT_TOOLBAR_TOOLTIP_DISPLAY_MAP_TOWN_DIRECTORY
),
2522 NWidget(NWID_SPACER
),
2523 NWidget(WWT_PUSHIMGBTN
, COLOUR_GREY
, WID_TE_ZOOM_IN
), SetDataTip(SPR_IMG_ZOOMIN
, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN
),
2524 NWidget(WWT_PUSHIMGBTN
, COLOUR_GREY
, WID_TE_ZOOM_OUT
), SetDataTip(SPR_IMG_ZOOMOUT
, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT
),
2525 NWidget(NWID_SPACER
),
2526 NWidget(WWT_PUSHIMGBTN
, COLOUR_GREY
, WID_TE_LAND_GENERATE
), SetDataTip(SPR_IMG_LANDSCAPING
, STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION
),
2527 NWidget(WWT_PUSHIMGBTN
, COLOUR_GREY
, WID_TE_TOWN_GENERATE
), SetDataTip(SPR_IMG_TOWN
, STR_SCENEDIT_TOOLBAR_TOWN_GENERATION
),
2528 NWidget(WWT_PUSHIMGBTN
, COLOUR_GREY
, WID_TE_INDUSTRY
), SetDataTip(SPR_IMG_INDUSTRY
, STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION
),
2529 NWidget(WWT_IMGBTN
, COLOUR_GREY
, WID_TE_ROADS
), SetDataTip(SPR_IMG_BUILDROAD
, STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION
),
2530 NWidget(WWT_IMGBTN
, COLOUR_GREY
, WID_TE_TRAMS
), SetDataTip(SPR_IMG_BUILDTRAMS
, STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION
),
2531 NWidget(WWT_PUSHIMGBTN
, COLOUR_GREY
, WID_TE_WATER
), SetDataTip(SPR_IMG_BUILDWATER
, STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS
),
2532 NWidget(WWT_PUSHIMGBTN
, COLOUR_GREY
, WID_TE_TREES
), SetDataTip(SPR_IMG_PLANTTREES
, STR_SCENEDIT_TOOLBAR_PLANT_TREES
),
2533 NWidget(WWT_PUSHIMGBTN
, COLOUR_GREY
, WID_TE_SIGNS
), SetDataTip(SPR_IMG_SIGN
, STR_SCENEDIT_TOOLBAR_PLACE_SIGN
),
2534 NWidget(NWID_SPACER
),
2535 NWidget(WWT_IMGBTN
, COLOUR_GREY
, WID_TE_MUSIC_SOUND
), SetDataTip(SPR_IMG_MUSIC
, STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW
),
2536 NWidget(WWT_IMGBTN
, COLOUR_GREY
, WID_TE_HELP
), SetDataTip(SPR_IMG_QUERY
, STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION
),
2537 NWidget(WWT_IMGBTN
, COLOUR_GREY
, WID_TE_SWITCH_BAR
), SetDataTip(SPR_IMG_SWITCH_TOOLBAR
, STR_TOOLBAR_TOOLTIP_SWITCH_TOOLBAR
),
2540 static std::unique_ptr
<NWidgetBase
> MakeScenarioToolbar()
2542 return MakeNWidgets(_nested_toolb_scen_inner_widgets
, std::make_unique
<NWidgetScenarioToolbarContainer
>());
2545 static constexpr NWidgetPart _nested_toolb_scen_widgets
[] = {
2546 NWidgetFunction(MakeScenarioToolbar
),
2549 static WindowDesc
_toolb_scen_desc(
2550 WDP_MANUAL
, nullptr, 0, 0,
2551 WC_MAIN_TOOLBAR
, WC_NONE
,
2552 WDF_NO_FOCUS
| WDF_NO_CLOSE
,
2553 _nested_toolb_scen_widgets
,
2554 &ScenarioEditorToolbarWindow::hotkeys
2557 /** Allocate the toolbar. */
2558 void AllocateToolbar()
2560 /* Clean old GUI values; railtype is (re)set by rail_gui.cpp */
2561 _last_built_roadtype
= ROADTYPE_ROAD
;
2562 _last_built_tramtype
= ROADTYPE_TRAM
;
2564 if (_game_mode
== GM_EDITOR
) {
2565 new ScenarioEditorToolbarWindow(_toolb_scen_desc
);
2567 new MainToolbarWindow(_toolb_normal_desc
);