00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "stdafx.h"
00013 #include "gui.h"
00014 #include "window_gui.h"
00015 #include "window_func.h"
00016 #include "viewport_func.h"
00017 #include "command_func.h"
00018 #include "vehicle_gui.h"
00019 #include "rail_gui.h"
00020 #include "road_gui.h"
00021 #include "date_func.h"
00022 #include "vehicle_func.h"
00023 #include "sound_func.h"
00024 #include "terraform_gui.h"
00025 #include "strings_func.h"
00026 #include "company_func.h"
00027 #include "company_gui.h"
00028 #include "vehicle_base.h"
00029 #include "cheat_func.h"
00030 #include "transparency_gui.h"
00031 #include "screenshot.h"
00032 #include "signs_func.h"
00033 #include "fios.h"
00034 #include "console_gui.h"
00035 #include "news_gui.h"
00036 #include "ai/ai_gui.hpp"
00037 #include "tilehighlight_func.h"
00038 #include "smallmap_gui.h"
00039 #include "graph_gui.h"
00040 #include "textbuf_gui.h"
00041 #include "linkgraph_gui.h"
00042 #include "newgrf_debug.h"
00043 #include "hotkeys.h"
00044 #include "engine_base.h"
00045
00046 #include "widgets/toolbar_widget.h"
00047
00048 #include "network/network.h"
00049 #include "network/network_gui.h"
00050 #include "network/network_func.h"
00051
00052
00053 RailType _last_built_railtype;
00054 RoadType _last_built_roadtype;
00055
00057 enum ToolbarMode {
00058 TB_NORMAL,
00059 TB_UPPER,
00060 TB_LOWER
00061 };
00062
00064 enum CallBackFunction {
00065 CBF_NONE,
00066 CBF_PLACE_SIGN,
00067 CBF_PLACE_LANDINFO,
00068 };
00069
00073 class DropDownListCheckedItem : public DropDownListStringItem {
00074 uint checkmark_width;
00075 public:
00076 bool checked;
00077
00078 DropDownListCheckedItem(StringID string, int result, bool masked, bool checked) : DropDownListStringItem(string, result, masked), checked(checked)
00079 {
00080 this->checkmark_width = GetStringBoundingBox(STR_JUST_CHECKMARK).width + 3;
00081 }
00082
00083 virtual ~DropDownListCheckedItem() {}
00084
00085 uint Width() const
00086 {
00087 return DropDownListStringItem::Width() + this->checkmark_width;
00088 }
00089
00090 void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const
00091 {
00092 bool rtl = _current_text_dir == TD_RTL;
00093 if (this->checked) {
00094 DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, STR_JUST_CHECKMARK, sel ? TC_WHITE : TC_BLACK);
00095 }
00096 DrawString(left + WD_FRAMERECT_LEFT + (rtl ? 0 : this->checkmark_width), right - WD_FRAMERECT_RIGHT - (rtl ? this->checkmark_width : 0), top, this->String(), sel ? TC_WHITE : TC_BLACK);
00097 }
00098 };
00099
00103 class DropDownListCompanyItem : public DropDownListItem {
00104 Dimension icon_size;
00105 public:
00106 bool greyed;
00107
00108 DropDownListCompanyItem(int result, bool masked, bool greyed) : DropDownListItem(result, masked), greyed(greyed)
00109 {
00110 this->icon_size = GetSpriteSize(SPR_COMPANY_ICON);
00111 }
00112
00113 virtual ~DropDownListCompanyItem() {}
00114
00115 bool Selectable() const
00116 {
00117 return true;
00118 }
00119
00120 uint Width() const
00121 {
00122 CompanyID company = (CompanyID)this->result;
00123 SetDParam(0, company);
00124 SetDParam(1, company);
00125 return GetStringBoundingBox(STR_COMPANY_NAME_COMPANY_NUM).width + this->icon_size.width + 3;
00126 }
00127
00128 uint Height(uint width) const
00129 {
00130 return max(this->icon_size.height + 2U, (uint)FONT_HEIGHT_NORMAL);
00131 }
00132
00133 void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const
00134 {
00135 CompanyID company = (CompanyID)this->result;
00136 bool rtl = _current_text_dir == TD_RTL;
00137
00138
00139 if (!Company::IsValidID(company)) return;
00140
00141 int icon_offset = (bottom - top - icon_size.height) / 2;
00142 int text_offset = (bottom - top - FONT_HEIGHT_NORMAL) / 2;
00143
00144 DrawCompanyIcon(company, rtl ? right - this->icon_size.width - WD_FRAMERECT_RIGHT : left + WD_FRAMERECT_LEFT, top + icon_offset);
00145
00146 SetDParam(0, company);
00147 SetDParam(1, company);
00148 TextColour col;
00149 if (this->greyed) {
00150 col = (sel ? TC_SILVER : TC_GREY) | TC_NO_SHADE;
00151 } else {
00152 col = sel ? TC_WHITE : TC_BLACK;
00153 }
00154 DrawString(left + WD_FRAMERECT_LEFT + (rtl ? 0 : 3 + this->icon_size.width), right - WD_FRAMERECT_RIGHT - (rtl ? 3 + this->icon_size.width : 0), top + text_offset, STR_COMPANY_NAME_COMPANY_NUM, col);
00155 }
00156 };
00157
00161 static void PopupMainToolbMenu(Window *w, int widget, StringID string, int count)
00162 {
00163 DropDownList *list = new DropDownList();
00164 for (int i = 0; i < count; i++) {
00165 list->push_back(new DropDownListStringItem(string + i, i, false));
00166 }
00167 ShowDropDownList(w, list, 0, widget, 140, true, true);
00168 SndPlayFx(SND_15_BEEP);
00169 }
00170
00172 static const int CTMN_CLIENT_LIST = -1;
00173 static const int CTMN_NEW_COMPANY = -2;
00174 static const int CTMN_SPECTATE = -3;
00175
00179 static void PopupMainCompanyToolbMenu(Window *w, int widget, int grey = 0)
00180 {
00181 DropDownList *list = new DropDownList();
00182
00183 #ifdef ENABLE_NETWORK
00184 if (widget == WID_TN_COMPANIES && _networking) {
00185
00186 list->push_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_CLIENT_LIST, CTMN_CLIENT_LIST, false));
00187
00188 if (_local_company == COMPANY_SPECTATOR) {
00189 list->push_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_NEW_COMPANY, CTMN_NEW_COMPANY, NetworkMaxCompaniesReached()));
00190 } else {
00191 list->push_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_SPECTATE, CTMN_SPECTATE, NetworkMaxSpectatorsReached()));
00192 }
00193 }
00194 #endif
00195
00196 for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
00197 if (!Company::IsValidID(c)) continue;
00198 list->push_back(new DropDownListCompanyItem(c, false, HasBit(grey, c)));
00199 }
00200
00201 ShowDropDownList(w, list, _local_company == COMPANY_SPECTATOR ? CTMN_CLIENT_LIST : (int)_local_company, widget, 240, true, true);
00202 SndPlayFx(SND_15_BEEP);
00203 }
00204
00205
00206 static ToolbarMode _toolbar_mode;
00207
00208 static CallBackFunction SelectSignTool()
00209 {
00210 if (_cursor.sprite == SPR_CURSOR_SIGN) {
00211 ResetObjectToPlace();
00212 return CBF_NONE;
00213 } else {
00214 SetObjectToPlace(SPR_CURSOR_SIGN, PAL_NONE, HT_RECT, WC_MAIN_TOOLBAR, 0);
00215 return CBF_PLACE_SIGN;
00216 }
00217 }
00218
00219
00220
00221 static CallBackFunction ToolbarPauseClick(Window *w)
00222 {
00223 if (_networking && !_network_server) return CBF_NONE;
00224
00225 if (DoCommandP(0, PM_PAUSED_NORMAL, _pause_mode == PM_UNPAUSED, CMD_PAUSE)) SndPlayFx(SND_15_BEEP);
00226 return CBF_NONE;
00227 }
00228
00235 static CallBackFunction ToolbarFastForwardClick(Window *w)
00236 {
00237 _fast_forward ^= true;
00238 SndPlayFx(SND_15_BEEP);
00239 return CBF_NONE;
00240 }
00241
00245 enum OptionMenuEntries {
00246 OME_GAMEOPTIONS,
00247 OME_DIFFICULTIES,
00248 OME_SETTINGS,
00249 OME_SCRIPT_SETTINGS,
00250 OME_NEWGRFSETTINGS,
00251 OME_TRANSPARENCIES,
00252 OME_SHOW_TOWNNAMES,
00253 OME_SHOW_STATIONNAMES,
00254 OME_SHOW_WAYPOINTNAMES,
00255 OME_SHOW_SIGNS,
00256 OME_SHOW_COMPETITOR_SIGNS,
00257 OME_FULL_ANIMATION,
00258 OME_FULL_DETAILS,
00259 OME_TRANSPARENTBUILDINGS,
00260 OME_SHOW_STATIONSIGNS,
00261 };
00262
00269 static CallBackFunction ToolbarOptionsClick(Window *w)
00270 {
00271 DropDownList *list = new DropDownList();
00272 list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_GAME_OPTIONS, OME_GAMEOPTIONS, false));
00273 list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_DIFFICULTY_SETTINGS, OME_DIFFICULTIES, false));
00274 list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_CONFIG_SETTINGS, OME_SETTINGS, false));
00275
00276
00277
00278 if (!_networking || _network_server) list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_SCRIPT_SETTINGS, OME_SCRIPT_SETTINGS, false));
00279 list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_NEWGRF_SETTINGS, OME_NEWGRFSETTINGS, false));
00280 list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS, OME_TRANSPARENCIES, false));
00281 list->push_back(new DropDownListItem(-1, false));
00282 list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED, OME_SHOW_TOWNNAMES, false, HasBit(_display_opt, DO_SHOW_TOWN_NAMES)));
00283 list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED, OME_SHOW_STATIONNAMES, false, HasBit(_display_opt, DO_SHOW_STATION_NAMES)));
00284 list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED, OME_SHOW_WAYPOINTNAMES, false, HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES)));
00285 list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_SIGNS_DISPLAYED, OME_SHOW_SIGNS, false, HasBit(_display_opt, DO_SHOW_SIGNS)));
00286 list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS, OME_SHOW_COMPETITOR_SIGNS, false, HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS)));
00287 list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_FULL_ANIMATION, OME_FULL_ANIMATION, false, HasBit(_display_opt, DO_FULL_ANIMATION)));
00288 list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_FULL_DETAIL, OME_FULL_DETAILS, false, HasBit(_display_opt, DO_FULL_DETAIL)));
00289 list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS, OME_TRANSPARENTBUILDINGS, false, IsTransparencySet(TO_HOUSES)));
00290 list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_SIGNS, OME_SHOW_STATIONSIGNS, false, IsTransparencySet(TO_SIGNS)));
00291
00292 ShowDropDownList(w, list, 0, WID_TN_SETTINGS, 140, true, true);
00293 SndPlayFx(SND_15_BEEP);
00294 return CBF_NONE;
00295 }
00296
00303 static CallBackFunction MenuClickSettings(int index)
00304 {
00305 switch (index) {
00306 case OME_GAMEOPTIONS: ShowGameOptions(); return CBF_NONE;
00307 case OME_DIFFICULTIES: ShowGameDifficulty(); return CBF_NONE;
00308 case OME_SETTINGS: ShowGameSettings(); return CBF_NONE;
00309 case OME_SCRIPT_SETTINGS: ShowAIConfigWindow(); return CBF_NONE;
00310 case OME_NEWGRFSETTINGS: ShowNewGRFSettings(!_networking && _settings_client.gui.UserIsAllowedToChangeNewGRFs(), true, true, &_grfconfig); return CBF_NONE;
00311 case OME_TRANSPARENCIES: ShowTransparencyToolbar(); break;
00312
00313 case OME_SHOW_TOWNNAMES: ToggleBit(_display_opt, DO_SHOW_TOWN_NAMES); break;
00314 case OME_SHOW_STATIONNAMES: ToggleBit(_display_opt, DO_SHOW_STATION_NAMES); break;
00315 case OME_SHOW_WAYPOINTNAMES: ToggleBit(_display_opt, DO_SHOW_WAYPOINT_NAMES); break;
00316 case OME_SHOW_SIGNS: ToggleBit(_display_opt, DO_SHOW_SIGNS); break;
00317 case OME_SHOW_COMPETITOR_SIGNS:
00318 ToggleBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS);
00319 InvalidateWindowClassesData(WC_SIGN_LIST, -1);
00320 break;
00321 case OME_FULL_ANIMATION: ToggleBit(_display_opt, DO_FULL_ANIMATION); break;
00322 case OME_FULL_DETAILS: ToggleBit(_display_opt, DO_FULL_DETAIL); break;
00323 case OME_TRANSPARENTBUILDINGS: ToggleTransparency(TO_HOUSES); break;
00324 case OME_SHOW_STATIONSIGNS: ToggleTransparency(TO_SIGNS); break;
00325 }
00326 MarkWholeScreenDirty();
00327 return CBF_NONE;
00328 }
00329
00333 enum SaveLoadEditorMenuEntries {
00334 SLEME_SAVE_SCENARIO = 0,
00335 SLEME_LOAD_SCENARIO,
00336 SLEME_SAVE_HEIGHTMAP,
00337 SLEME_LOAD_HEIGHTMAP,
00338 SLEME_EXIT_TOINTRO,
00339 SLEME_EXIT_GAME = 6,
00340 SLEME_MENUCOUNT,
00341 };
00342
00346 enum SaveLoadNormalMenuEntries {
00347 SLNME_SAVE_GAME = 0,
00348 SLNME_LOAD_GAME,
00349 SLNME_EXIT_TOINTRO,
00350 SLNME_EXIT_GAME = 4,
00351 SLNME_MENUCOUNT,
00352 };
00353
00360 static CallBackFunction ToolbarSaveClick(Window *w)
00361 {
00362 PopupMainToolbMenu(w, WID_TN_SAVE, STR_FILE_MENU_SAVE_GAME, SLNME_MENUCOUNT);
00363 return CBF_NONE;
00364 }
00365
00372 static CallBackFunction ToolbarScenSaveOrLoad(Window *w)
00373 {
00374 PopupMainToolbMenu(w, WID_TE_SAVE, STR_SCENEDIT_FILE_MENU_SAVE_SCENARIO, SLEME_MENUCOUNT);
00375 return CBF_NONE;
00376 }
00377
00384 static CallBackFunction MenuClickSaveLoad(int index = 0)
00385 {
00386 if (_game_mode == GM_EDITOR) {
00387 switch (index) {
00388 case SLEME_SAVE_SCENARIO: ShowSaveLoadDialog(SLD_SAVE_SCENARIO); break;
00389 case SLEME_LOAD_SCENARIO: ShowSaveLoadDialog(SLD_LOAD_SCENARIO); break;
00390 case SLEME_SAVE_HEIGHTMAP: ShowSaveLoadDialog(SLD_SAVE_HEIGHTMAP); break;
00391 case SLEME_LOAD_HEIGHTMAP: ShowSaveLoadDialog(SLD_LOAD_HEIGHTMAP); break;
00392 case SLEME_EXIT_TOINTRO: AskExitToGameMenu(); break;
00393 case SLEME_EXIT_GAME: HandleExitGameRequest(); break;
00394 }
00395 } else {
00396 switch (index) {
00397 case SLNME_SAVE_GAME: ShowSaveLoadDialog(SLD_SAVE_GAME); break;
00398 case SLNME_LOAD_GAME: ShowSaveLoadDialog(SLD_LOAD_GAME); break;
00399 case SLNME_EXIT_TOINTRO: AskExitToGameMenu(); break;
00400 case SLNME_EXIT_GAME: HandleExitGameRequest(); break;
00401 }
00402 }
00403 return CBF_NONE;
00404 }
00405
00406
00407
00408 enum MapMenuEntries {
00409 MME_SHOW_SMALLMAP = 0,
00410 MME_SHOW_EXTRAVIEWPORTS,
00411 MME_SHOW_LINKGRAPH,
00412 MME_SHOW_SIGNLISTS,
00413 MME_SHOW_TOWNDIRECTORY,
00414 MME_MENUCOUNT_NORMAL = 4,
00415 MME_MENUCOUNT_EDITOR = 5,
00416 };
00417
00418 static CallBackFunction ToolbarMapClick(Window *w)
00419 {
00420 PopupMainToolbMenu(w, WID_TN_SMALL_MAP, STR_MAP_MENU_MAP_OF_WORLD, MME_MENUCOUNT_NORMAL);
00421 return CBF_NONE;
00422 }
00423
00424 static CallBackFunction ToolbarScenMapTownDir(Window *w)
00425 {
00426 PopupMainToolbMenu(w, WID_TE_SMALL_MAP, STR_MAP_MENU_MAP_OF_WORLD, MME_MENUCOUNT_EDITOR);
00427 return CBF_NONE;
00428 }
00429
00436 static CallBackFunction MenuClickMap(int index)
00437 {
00438 switch (index) {
00439 case MME_SHOW_SMALLMAP: ShowSmallMap(); break;
00440 case MME_SHOW_EXTRAVIEWPORTS: ShowExtraViewPortWindow(); break;
00441 case MME_SHOW_LINKGRAPH: ShowLinkGraphLegend(); break;
00442 case MME_SHOW_SIGNLISTS: ShowSignList(); break;
00443 case MME_SHOW_TOWNDIRECTORY: if (_game_mode == GM_EDITOR) ShowTownDirectory(); break;
00444 }
00445 return CBF_NONE;
00446 }
00447
00448
00449
00450 static CallBackFunction ToolbarTownClick(Window *w)
00451 {
00452 PopupMainToolbMenu(w, WID_TN_TOWNS, STR_TOWN_MENU_TOWN_DIRECTORY, (_settings_game.economy.found_town == TF_FORBIDDEN) ? 1 : 2);
00453 return CBF_NONE;
00454 }
00455
00462 static CallBackFunction MenuClickTown(int index)
00463 {
00464 switch (index) {
00465 case 0: ShowTownDirectory(); break;
00466 case 1:
00467 if (_settings_game.economy.found_town != TF_FORBIDDEN) ShowFoundTownWindow();
00468 break;
00469 }
00470 return CBF_NONE;
00471 }
00472
00473
00474
00475 static CallBackFunction ToolbarSubsidiesClick(Window *w)
00476 {
00477 PopupMainToolbMenu(w, WID_TN_SUBSIDIES, STR_SUBSIDIES_MENU_SUBSIDIES, 2);
00478 return CBF_NONE;
00479 }
00480
00487 static CallBackFunction MenuClickSubsidies(int index)
00488 {
00489 switch (index) {
00490 case 0: ShowSubsidiesList(); break;
00491 case 1: ShowGoalsList(); break;
00492 }
00493 return CBF_NONE;
00494 }
00495
00496
00497
00498 static CallBackFunction ToolbarStationsClick(Window *w)
00499 {
00500 PopupMainCompanyToolbMenu(w, WID_TN_STATIONS);
00501 return CBF_NONE;
00502 }
00503
00510 static CallBackFunction MenuClickStations(int index)
00511 {
00512 ShowCompanyStations((CompanyID)index);
00513 return CBF_NONE;
00514 }
00515
00516
00517
00518 static CallBackFunction ToolbarFinancesClick(Window *w)
00519 {
00520 PopupMainCompanyToolbMenu(w, WID_TN_FINANCES);
00521 return CBF_NONE;
00522 }
00523
00530 static CallBackFunction MenuClickFinances(int index)
00531 {
00532 ShowCompanyFinances((CompanyID)index);
00533 return CBF_NONE;
00534 }
00535
00536
00537
00538 static CallBackFunction ToolbarCompaniesClick(Window *w)
00539 {
00540 PopupMainCompanyToolbMenu(w, WID_TN_COMPANIES);
00541 return CBF_NONE;
00542 }
00543
00550 static CallBackFunction MenuClickCompany(int index)
00551 {
00552 #ifdef ENABLE_NETWORK
00553 if (_networking) {
00554 switch (index) {
00555 case CTMN_CLIENT_LIST:
00556 ShowClientList();
00557 return CBF_NONE;
00558
00559 case CTMN_NEW_COMPANY:
00560 if (_network_server) {
00561 DoCommandP(0, 0, _network_own_client_id, CMD_COMPANY_CTRL);
00562 } else {
00563 NetworkSendCommand(0, 0, 0, CMD_COMPANY_CTRL, NULL, NULL, _local_company);
00564 }
00565 return CBF_NONE;
00566
00567 case CTMN_SPECTATE:
00568 if (_network_server) {
00569 NetworkServerDoMove(CLIENT_ID_SERVER, COMPANY_SPECTATOR);
00570 MarkWholeScreenDirty();
00571 } else {
00572 NetworkClientRequestMove(COMPANY_SPECTATOR);
00573 }
00574 return CBF_NONE;
00575 }
00576 }
00577 #endif
00578 ShowCompany((CompanyID)index);
00579 return CBF_NONE;
00580 }
00581
00582
00583
00584 static CallBackFunction ToolbarGraphsClick(Window *w)
00585 {
00586 PopupMainToolbMenu(w, WID_TN_GRAPHS, STR_GRAPH_MENU_OPERATING_PROFIT_GRAPH, (_toolbar_mode == TB_NORMAL) ? 6 : 8);
00587 return CBF_NONE;
00588 }
00589
00596 static CallBackFunction MenuClickGraphs(int index)
00597 {
00598 switch (index) {
00599 case 0: ShowOperatingProfitGraph(); break;
00600 case 1: ShowIncomeGraph(); break;
00601 case 2: ShowDeliveredCargoGraph(); break;
00602 case 3: ShowPerformanceHistoryGraph(); break;
00603 case 4: ShowCompanyValueGraph(); break;
00604 case 5: ShowCargoPaymentRates(); break;
00605
00606 case 6: ShowCompanyLeagueTable(); break;
00607 case 7: ShowPerformanceRatingDetail(); break;
00608 }
00609 return CBF_NONE;
00610 }
00611
00612
00613
00614 static CallBackFunction ToolbarLeagueClick(Window *w)
00615 {
00616 PopupMainToolbMenu(w, WID_TN_LEAGUE, STR_GRAPH_MENU_COMPANY_LEAGUE_TABLE, 2);
00617 return CBF_NONE;
00618 }
00619
00626 static CallBackFunction MenuClickLeague(int index)
00627 {
00628 switch (index) {
00629 case 0: ShowCompanyLeagueTable(); break;
00630 case 1: ShowPerformanceRatingDetail(); break;
00631 }
00632 return CBF_NONE;
00633 }
00634
00635
00636
00637 static CallBackFunction ToolbarIndustryClick(Window *w)
00638 {
00639
00640 PopupMainToolbMenu(w, WID_TN_INDUSTRIES, STR_INDUSTRY_MENU_INDUSTRY_DIRECTORY, (_local_company == COMPANY_SPECTATOR) ? 2 : 3);
00641 return CBF_NONE;
00642 }
00643
00650 static CallBackFunction MenuClickIndustry(int index)
00651 {
00652 switch (index) {
00653 case 0: ShowIndustryDirectory(); break;
00654 case 1: ShowIndustryCargoesWindow(); break;
00655 case 2: ShowBuildIndustryWindow(); break;
00656 }
00657 return CBF_NONE;
00658 }
00659
00660
00661
00662 static void ToolbarVehicleClick(Window *w, VehicleType veh)
00663 {
00664 const Vehicle *v;
00665 int dis = ~0;
00666
00667 FOR_ALL_VEHICLES(v) {
00668 if (v->type == veh && v->IsPrimaryVehicle()) ClrBit(dis, v->owner);
00669 }
00670 PopupMainCompanyToolbMenu(w, WID_TN_VEHICLE_START + veh, dis);
00671 }
00672
00673
00674 static CallBackFunction ToolbarTrainClick(Window *w)
00675 {
00676 ToolbarVehicleClick(w, VEH_TRAIN);
00677 return CBF_NONE;
00678 }
00679
00686 static CallBackFunction MenuClickShowTrains(int index)
00687 {
00688 ShowVehicleListWindow((CompanyID)index, VEH_TRAIN);
00689 return CBF_NONE;
00690 }
00691
00692
00693
00694 static CallBackFunction ToolbarRoadClick(Window *w)
00695 {
00696 ToolbarVehicleClick(w, VEH_ROAD);
00697 return CBF_NONE;
00698 }
00699
00706 static CallBackFunction MenuClickShowRoad(int index)
00707 {
00708 ShowVehicleListWindow((CompanyID)index, VEH_ROAD);
00709 return CBF_NONE;
00710 }
00711
00712
00713
00714 static CallBackFunction ToolbarShipClick(Window *w)
00715 {
00716 ToolbarVehicleClick(w, VEH_SHIP);
00717 return CBF_NONE;
00718 }
00719
00726 static CallBackFunction MenuClickShowShips(int index)
00727 {
00728 ShowVehicleListWindow((CompanyID)index, VEH_SHIP);
00729 return CBF_NONE;
00730 }
00731
00732
00733
00734 static CallBackFunction ToolbarAirClick(Window *w)
00735 {
00736 ToolbarVehicleClick(w, VEH_AIRCRAFT);
00737 return CBF_NONE;
00738 }
00739
00746 static CallBackFunction MenuClickShowAir(int index)
00747 {
00748 ShowVehicleListWindow((CompanyID)index, VEH_AIRCRAFT);
00749 return CBF_NONE;
00750 }
00751
00752
00753
00754 static CallBackFunction ToolbarZoomInClick(Window *w)
00755 {
00756 if (DoZoomInOutWindow(ZOOM_IN, FindWindowById(WC_MAIN_WINDOW, 0))) {
00757 w->HandleButtonClick((_game_mode == GM_EDITOR) ? (byte)WID_TE_ZOOM_IN : (byte)WID_TN_ZOOM_IN);
00758 SndPlayFx(SND_15_BEEP);
00759 }
00760 return CBF_NONE;
00761 }
00762
00763
00764
00765 static CallBackFunction ToolbarZoomOutClick(Window *w)
00766 {
00767 if (DoZoomInOutWindow(ZOOM_OUT, FindWindowById(WC_MAIN_WINDOW, 0))) {
00768 w->HandleButtonClick((_game_mode == GM_EDITOR) ? (byte)WID_TE_ZOOM_OUT : (byte)WID_TN_ZOOM_OUT);
00769 SndPlayFx(SND_15_BEEP);
00770 }
00771 return CBF_NONE;
00772 }
00773
00774
00775
00776 static CallBackFunction ToolbarBuildRailClick(Window *w)
00777 {
00778 ShowDropDownList(w, GetRailTypeDropDownList(), _last_built_railtype, WID_TN_RAILS, 140, true, true);
00779 SndPlayFx(SND_15_BEEP);
00780 return CBF_NONE;
00781 }
00782
00789 static CallBackFunction MenuClickBuildRail(int index)
00790 {
00791 _last_built_railtype = (RailType)index;
00792 ShowBuildRailToolbar(_last_built_railtype);
00793 return CBF_NONE;
00794 }
00795
00796
00797
00798 static CallBackFunction ToolbarBuildRoadClick(Window *w)
00799 {
00800 const Company *c = Company::Get(_local_company);
00801 DropDownList *list = new DropDownList();
00802
00803
00804 list->push_back(new DropDownListStringItem(STR_ROAD_MENU_ROAD_CONSTRUCTION, ROADTYPE_ROAD, false));
00805
00806
00807 Engine *e;
00808 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
00809 if (!HasBit(e->info.climates, _settings_game.game_creation.landscape)) continue;
00810 if (!HasBit(e->info.misc_flags, EF_ROAD_TRAM)) continue;
00811
00812 list->push_back(new DropDownListStringItem(STR_ROAD_MENU_TRAM_CONSTRUCTION, ROADTYPE_TRAM, !HasBit(c->avail_roadtypes, ROADTYPE_TRAM)));
00813 break;
00814 }
00815 ShowDropDownList(w, list, _last_built_roadtype, WID_TN_ROADS, 140, true, true);
00816 SndPlayFx(SND_15_BEEP);
00817 return CBF_NONE;
00818 }
00819
00826 static CallBackFunction MenuClickBuildRoad(int index)
00827 {
00828 _last_built_roadtype = (RoadType)index;
00829 ShowBuildRoadToolbar(_last_built_roadtype);
00830 return CBF_NONE;
00831 }
00832
00833
00834
00835 static CallBackFunction ToolbarBuildWaterClick(Window *w)
00836 {
00837 PopupMainToolbMenu(w, WID_TN_WATER, STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION, 1);
00838 return CBF_NONE;
00839 }
00840
00847 static CallBackFunction MenuClickBuildWater(int index)
00848 {
00849 ShowBuildDocksToolbar();
00850 return CBF_NONE;
00851 }
00852
00853
00854
00855 static CallBackFunction ToolbarBuildAirClick(Window *w)
00856 {
00857 PopupMainToolbMenu(w, WID_TN_AIR, STR_AIRCRAFT_MENU_AIRPORT_CONSTRUCTION, 1);
00858 return CBF_NONE;
00859 }
00860
00867 static CallBackFunction MenuClickBuildAir(int index)
00868 {
00869 ShowBuildAirToolbar();
00870 return CBF_NONE;
00871 }
00872
00873
00874
00875 static CallBackFunction ToolbarForestClick(Window *w)
00876 {
00877 PopupMainToolbMenu(w, WID_TN_LANDSCAPE, STR_LANDSCAPING_MENU_LANDSCAPING, 3);
00878 return CBF_NONE;
00879 }
00880
00887 static CallBackFunction MenuClickForest(int index)
00888 {
00889 switch (index) {
00890 case 0: ShowTerraformToolbar(); break;
00891 case 1: ShowBuildTreesToolbar(); break;
00892 case 2: return SelectSignTool();
00893 }
00894 return CBF_NONE;
00895 }
00896
00897
00898
00899 static CallBackFunction ToolbarMusicClick(Window *w)
00900 {
00901 PopupMainToolbMenu(w, WID_TN_MUSIC_SOUND, STR_TOOLBAR_SOUND_MUSIC, 1);
00902 return CBF_NONE;
00903 }
00904
00911 static CallBackFunction MenuClickMusicWindow(int index)
00912 {
00913 ShowMusicWindow();
00914 return CBF_NONE;
00915 }
00916
00917
00918
00919 static CallBackFunction ToolbarNewspaperClick(Window *w)
00920 {
00921 PopupMainToolbMenu(w, WID_TN_MESSAGES, STR_NEWS_MENU_LAST_MESSAGE_NEWS_REPORT, 3);
00922 return CBF_NONE;
00923 }
00924
00931 static CallBackFunction MenuClickNewspaper(int index)
00932 {
00933 switch (index) {
00934 case 0: ShowLastNewsMessage(); break;
00935 case 1: ShowMessageOptions(); break;
00936 case 2: ShowMessageHistory(); break;
00937 }
00938 return CBF_NONE;
00939 }
00940
00941
00942
00943 static CallBackFunction PlaceLandBlockInfo()
00944 {
00945 if (_cursor.sprite == SPR_CURSOR_QUERY) {
00946 ResetObjectToPlace();
00947 return CBF_NONE;
00948 } else {
00949 SetObjectToPlace(SPR_CURSOR_QUERY, PAL_NONE, HT_RECT, WC_MAIN_TOOLBAR, 0);
00950 return CBF_PLACE_LANDINFO;
00951 }
00952 }
00953
00954 static CallBackFunction ToolbarHelpClick(Window *w)
00955 {
00956 PopupMainToolbMenu(w, WID_TN_HELP, STR_ABOUT_MENU_LAND_BLOCK_INFO, _settings_client.gui.newgrf_developer_tools ? 12 : 9);
00957 return CBF_NONE;
00958 }
00959
00960 static void MenuClickSmallScreenshot()
00961 {
00962 MakeScreenshot(SC_VIEWPORT, NULL);
00963 }
00964
00965 static void MenuClickZoomedInScreenshot()
00966 {
00967 MakeScreenshot(SC_ZOOMEDIN, NULL);
00968 }
00969
00970 static void MenuClickDefaultZoomScreenshot()
00971 {
00972 MakeScreenshot(SC_DEFAULTZOOM, NULL);
00973 }
00974
00975 static void MenuClickWorldScreenshot()
00976 {
00977 MakeScreenshot(SC_WORLD, NULL);
00978 }
00979
00987 void ToggleBoundingBoxes()
00988 {
00989 extern bool _draw_bounding_boxes;
00990
00991 if (_settings_client.gui.newgrf_developer_tools || _draw_bounding_boxes) {
00992 _draw_bounding_boxes = !_draw_bounding_boxes;
00993 MarkWholeScreenDirty();
00994 }
00995 }
00996
01004 void ToggleDirtyBlocks()
01005 {
01006 extern bool _draw_dirty_blocks;
01007
01008 if (_settings_client.gui.newgrf_developer_tools || _draw_dirty_blocks) {
01009 _draw_dirty_blocks = !_draw_dirty_blocks;
01010 MarkWholeScreenDirty();
01011 }
01012 }
01013
01019 static CallBackFunction MenuClickHelp(int index)
01020 {
01021 switch (index) {
01022 case 0: return PlaceLandBlockInfo();
01023 case 2: IConsoleSwitch(); break;
01024 case 3: ShowAIDebugWindow(); break;
01025 case 4: MenuClickSmallScreenshot(); break;
01026 case 5: MenuClickZoomedInScreenshot(); break;
01027 case 6: MenuClickDefaultZoomScreenshot(); break;
01028 case 7: MenuClickWorldScreenshot(); break;
01029 case 8: ShowAboutWindow(); break;
01030 case 9: ShowSpriteAlignerWindow(); break;
01031 case 10: ToggleBoundingBoxes(); break;
01032 case 11: ToggleDirtyBlocks(); break;
01033 }
01034 return CBF_NONE;
01035 }
01036
01037
01038
01039 static CallBackFunction ToolbarSwitchClick(Window *w)
01040 {
01041 if (_toolbar_mode != TB_LOWER) {
01042 _toolbar_mode = TB_LOWER;
01043 } else {
01044 _toolbar_mode = TB_UPPER;
01045 }
01046
01047 w->ReInit();
01048 w->SetWidgetLoweredState(WID_TN_SWITCH_BAR, _toolbar_mode == TB_LOWER);
01049 SndPlayFx(SND_15_BEEP);
01050 return CBF_NONE;
01051 }
01052
01053
01054
01058 static CallBackFunction ToolbarScenDatePanel(Window *w)
01059 {
01060 SetDParam(0, _settings_game.game_creation.starting_year);
01061 ShowQueryString(STR_JUST_INT, STR_MAPGEN_START_DATE_QUERY_CAPT, 8, w, CS_NUMERAL, QSF_ENABLE_DEFAULT);
01062 _left_button_clicked = false;
01063 return CBF_NONE;
01064 }
01065
01066 static CallBackFunction ToolbarScenDateBackward(Window *w)
01067 {
01068
01069 if (!(w->flags & WF_TIMEOUT) || w->timeout_timer <= 1) {
01070 w->HandleButtonClick(WID_TE_DATE_BACKWARD);
01071 w->SetDirty();
01072
01073 _settings_game.game_creation.starting_year = Clamp(_settings_game.game_creation.starting_year - 1, MIN_YEAR, MAX_YEAR);
01074 SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0);
01075 }
01076 _left_button_clicked = false;
01077 return CBF_NONE;
01078 }
01079
01080 static CallBackFunction ToolbarScenDateForward(Window *w)
01081 {
01082
01083 if (!(w->flags & WF_TIMEOUT) || w->timeout_timer <= 1) {
01084 w->HandleButtonClick(WID_TE_DATE_FORWARD);
01085 w->SetDirty();
01086
01087 _settings_game.game_creation.starting_year = Clamp(_settings_game.game_creation.starting_year + 1, MIN_YEAR, MAX_YEAR);
01088 SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0);
01089 }
01090 _left_button_clicked = false;
01091 return CBF_NONE;
01092 }
01093
01094 static CallBackFunction ToolbarScenGenLand(Window *w)
01095 {
01096 w->HandleButtonClick(WID_TE_LAND_GENERATE);
01097 SndPlayFx(SND_15_BEEP);
01098
01099 ShowEditorTerraformToolbar();
01100 return CBF_NONE;
01101 }
01102
01103
01104 static CallBackFunction ToolbarScenGenTown(Window *w)
01105 {
01106 w->HandleButtonClick(WID_TE_TOWN_GENERATE);
01107 SndPlayFx(SND_15_BEEP);
01108 ShowFoundTownWindow();
01109 return CBF_NONE;
01110 }
01111
01112 static CallBackFunction ToolbarScenGenIndustry(Window *w)
01113 {
01114 w->HandleButtonClick(WID_TE_INDUSTRY);
01115 SndPlayFx(SND_15_BEEP);
01116 ShowBuildIndustryWindow();
01117 return CBF_NONE;
01118 }
01119
01120 static CallBackFunction ToolbarScenBuildRoad(Window *w)
01121 {
01122 w->HandleButtonClick(WID_TE_ROADS);
01123 SndPlayFx(SND_15_BEEP);
01124 ShowBuildRoadScenToolbar();
01125 return CBF_NONE;
01126 }
01127
01128 static CallBackFunction ToolbarScenBuildDocks(Window *w)
01129 {
01130 w->HandleButtonClick(WID_TE_WATER);
01131 SndPlayFx(SND_15_BEEP);
01132 ShowBuildDocksScenToolbar();
01133 return CBF_NONE;
01134 }
01135
01136 static CallBackFunction ToolbarScenPlantTrees(Window *w)
01137 {
01138 w->HandleButtonClick(WID_TE_TREES);
01139 SndPlayFx(SND_15_BEEP);
01140 ShowBuildTreesToolbar();
01141 return CBF_NONE;
01142 }
01143
01144 static CallBackFunction ToolbarScenPlaceSign(Window *w)
01145 {
01146 w->HandleButtonClick(WID_TE_SIGNS);
01147 SndPlayFx(SND_15_BEEP);
01148 return SelectSignTool();
01149 }
01150
01151 static CallBackFunction ToolbarBtn_NULL(Window *w)
01152 {
01153 return CBF_NONE;
01154 }
01155
01156 typedef CallBackFunction MenuClickedProc(int index);
01157
01158 static MenuClickedProc * const _menu_clicked_procs[] = {
01159 NULL,
01160 NULL,
01161 MenuClickSettings,
01162 MenuClickSaveLoad,
01163 MenuClickMap,
01164 MenuClickTown,
01165 MenuClickSubsidies,
01166 MenuClickStations,
01167 MenuClickFinances,
01168 MenuClickCompany,
01169 MenuClickGraphs,
01170 MenuClickLeague,
01171 MenuClickIndustry,
01172 MenuClickShowTrains,
01173 MenuClickShowRoad,
01174 MenuClickShowShips,
01175 MenuClickShowAir,
01176 MenuClickMap,
01177 NULL,
01178 MenuClickBuildRail,
01179 MenuClickBuildRoad,
01180 MenuClickBuildWater,
01181 MenuClickBuildAir,
01182 MenuClickForest,
01183 MenuClickMusicWindow,
01184 MenuClickNewspaper,
01185 MenuClickHelp,
01186 };
01187
01188 int16 *_preferred_toolbar_size = NULL;
01189
01191 class NWidgetToolbarContainer : public NWidgetContainer {
01192 bool visible[WID_TN_END];
01193 protected:
01194 uint spacers;
01195
01196 public:
01197 NWidgetToolbarContainer() : NWidgetContainer(NWID_HORIZONTAL)
01198 {
01199 }
01200
01206 bool IsButton(WidgetType type) const
01207 {
01208 return type == WWT_IMGBTN || type == WWT_IMGBTN_2 || type == WWT_PUSHIMGBTN;
01209 }
01210
01211 void SetupSmallestSize(Window *w, bool init_array)
01212 {
01213 this->smallest_x = 0;
01214 this->smallest_y = 0;
01215 this->fill_x = 1;
01216 this->fill_y = 0;
01217 this->resize_x = 1;
01218 this->resize_y = 0;
01219 this->spacers = 0;
01220
01221 uint nbuttons = 0;
01222
01223 for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
01224 child_wid->SetupSmallestSize(w, init_array);
01225 this->smallest_y = max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom);
01226 if (this->IsButton(child_wid->type)) {
01227 nbuttons++;
01228 this->smallest_x = max(this->smallest_x, child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right);
01229 } else if (child_wid->type == NWID_SPACER) {
01230 this->spacers++;
01231 }
01232 }
01233
01234
01235 for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
01236 child_wid->current_y = this->smallest_y;
01237 if (!this->IsButton(child_wid->type)) {
01238 child_wid->current_x = child_wid->smallest_x;
01239 }
01240 }
01241 *_preferred_toolbar_size = nbuttons * this->smallest_x;
01242 }
01243
01244 void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl)
01245 {
01246 assert(given_width >= this->smallest_x && given_height >= this->smallest_y);
01247
01248 this->pos_x = x;
01249 this->pos_y = y;
01250 this->current_x = given_width;
01251 this->current_y = given_height;
01252
01253
01254 memset(this->visible, 0, sizeof(this->visible));
01255 uint arrangable_count, button_count, spacer_count;
01256 const byte *arrangement = GetButtonArrangement(given_width, arrangable_count, button_count, spacer_count);
01257 for (uint i = 0; i < arrangable_count; i++) {
01258 this->visible[arrangement[i]] = true;
01259 }
01260
01261
01262 NWidgetBase *widgets[WID_TN_END];
01263 for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
01264 if (child_wid->type == NWID_SPACER) continue;
01265 widgets[((NWidgetCore*)child_wid)->index] = child_wid;
01266 }
01267
01268
01269 uint position = 0;
01270 uint spacer_space = max(0, (int)given_width - (int)(button_count * this->smallest_x));
01271 uint button_space = given_width - spacer_space;
01272 uint spacer_i = 0;
01273 uint button_i = 0;
01274
01275
01276 const byte *cur_wid = rtl ? &arrangement[arrangable_count - 1] : arrangement;
01277 for (uint i = 0; i < arrangable_count; i++) {
01278 NWidgetBase *child_wid = widgets[*cur_wid];
01279
01280 if (spacer_space != 0) {
01281 NWidgetBase *possible_spacer = rtl ? child_wid->next : child_wid->prev;
01282 if (possible_spacer != NULL && possible_spacer->type == NWID_SPACER) {
01283 uint add = spacer_space / (spacer_count - spacer_i);
01284 position += add;
01285 spacer_space -= add;
01286 spacer_i++;
01287 }
01288 }
01289
01290
01291 if (this->IsButton(child_wid->type)) {
01292 child_wid->current_x = button_space / (button_count - button_i);
01293 button_space -= child_wid->current_x;
01294 button_i++;
01295 }
01296 child_wid->AssignSizePosition(sizing, x + position, y, child_wid->current_x, this->current_y, rtl);
01297 position += child_wid->current_x;
01298
01299 if (rtl) {
01300 cur_wid--;
01301 } else {
01302 cur_wid++;
01303 }
01304 }
01305 }
01306
01307 void Draw(const Window *w)
01308 {
01309
01310 GfxFillRect(this->pos_x, this->pos_y, this->pos_x + this->current_x - 1, this->pos_y + this->current_y - 1, PC_VERY_DARK_RED);
01311 GfxFillRect(this->pos_x, this->pos_y, this->pos_x + this->current_x - 1, this->pos_y + this->current_y - 1, PC_DARK_RED, FILLRECT_CHECKER);
01312
01313 bool rtl = _current_text_dir == TD_RTL;
01314 for (NWidgetBase *child_wid = rtl ? this->tail : this->head; child_wid != NULL; child_wid = rtl ? child_wid->prev : child_wid->next) {
01315 if (child_wid->type == NWID_SPACER) continue;
01316 if (!this->visible[((NWidgetCore*)child_wid)->index]) continue;
01317
01318 child_wid->Draw(w);
01319 }
01320 }
01321
01322 NWidgetCore *GetWidgetFromPos(int x, int y)
01323 {
01324 if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return NULL;
01325
01326 for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
01327 if (child_wid->type == NWID_SPACER) continue;
01328 if (!this->visible[((NWidgetCore*)child_wid)->index]) continue;
01329
01330 NWidgetCore *nwid = child_wid->GetWidgetFromPos(x, y);
01331 if (nwid != NULL) return nwid;
01332 }
01333 return NULL;
01334 }
01335
01344 virtual const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const = 0;
01345 };
01346
01348 class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
01349 const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const
01350 {
01351 static const uint SMALLEST_ARRANGEMENT = 14;
01352 static const uint BIGGEST_ARRANGEMENT = 19;
01353 static const byte arrange14[] = {
01354 0, 1, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 27,
01355 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 24, 25, 26, 27,
01356 };
01357 static const byte arrange15[] = {
01358 0, 1, 4, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
01359 0, 2, 4, 3, 5, 6, 7, 8, 9, 10, 12, 24, 25, 26, 27,
01360 };
01361 static const byte arrange16[] = {
01362 0, 1, 2, 4, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
01363 0, 1, 3, 5, 6, 7, 8, 9, 10, 12, 24, 25, 26, 17, 18, 27,
01364 };
01365 static const byte arrange17[] = {
01366 0, 1, 2, 4, 6, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
01367 0, 1, 3, 4, 6, 5, 7, 8, 9, 10, 12, 24, 25, 26, 17, 18, 27,
01368 };
01369 static const byte arrange18[] = {
01370 0, 1, 2, 4, 5, 6, 7, 8, 9, 12, 19, 20, 21, 22, 23, 17, 18, 27,
01371 0, 1, 3, 4, 5, 6, 7, 10, 13, 14, 15, 16, 24, 25, 26, 17, 18, 27,
01372 };
01373 static const byte arrange19[] = {
01374 0, 1, 2, 4, 5, 6, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 17, 18, 27,
01375 0, 1, 3, 4, 7, 8, 9, 10, 12, 25, 19, 20, 21, 22, 23, 26, 17, 18, 27,
01376 };
01377 static const byte arrange_all[] = {
01378 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
01379 };
01380
01381
01382 uint full_buttons = max(CeilDiv(width, this->smallest_x), SMALLEST_ARRANGEMENT);
01383 if (full_buttons > BIGGEST_ARRANGEMENT) {
01384 button_count = arrangable_count = lengthof(arrange_all);
01385 spacer_count = this->spacers;
01386 return arrange_all;
01387 }
01388
01389
01390 static const byte * const arrangements[] = { arrange14, arrange15, arrange16, arrange17, arrange18, arrange19 };
01391
01392 button_count = arrangable_count = full_buttons;
01393 spacer_count = this->spacers;
01394 return arrangements[full_buttons - SMALLEST_ARRANGEMENT] + ((_toolbar_mode == TB_LOWER) ? full_buttons : 0);
01395 }
01396 };
01397
01399 class NWidgetScenarioToolbarContainer : public NWidgetToolbarContainer {
01400 uint panel_widths[2];
01401
01402 void SetupSmallestSize(Window *w, bool init_array)
01403 {
01404 this->NWidgetToolbarContainer::SetupSmallestSize(w, init_array);
01405
01406
01407 uint i = 0;
01408 for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
01409 if (child_wid->type == NWID_SPACER || this->IsButton(child_wid->type)) continue;
01410
01411 assert(i < lengthof(this->panel_widths));
01412 this->panel_widths[i++] = child_wid->current_x;
01413 *_preferred_toolbar_size += child_wid->current_x;
01414 }
01415 }
01416
01417 const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const
01418 {
01419 static const byte arrange_all[] = {
01420 0, 1, 2, 3, 4, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 24, 26,
01421 };
01422 static const byte arrange_nopanel[] = {
01423 0, 1, 2, 3, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 24, 26,
01424 };
01425 static const byte arrange_switch[] = {
01426 18, 8, 11, 12, 13, 14, 15, 16, 17, 27,
01427 0, 1, 2, 3, 18, 9, 10, 24, 26, 27,
01428 };
01429
01430
01431 uint min_full_width = (lengthof(arrange_all) - lengthof(this->panel_widths)) * this->smallest_x + this->panel_widths[0] + this->panel_widths[1];
01432 if (width >= min_full_width) {
01433 width -= this->panel_widths[0] + this->panel_widths[1];
01434 arrangable_count = lengthof(arrange_all);
01435 button_count = arrangable_count - 2;
01436 spacer_count = this->spacers;
01437 return arrange_all;
01438 }
01439
01440
01441 uint min_small_width = (lengthof(arrange_switch) - lengthof(this->panel_widths)) * this->smallest_x / 2 + this->panel_widths[1];
01442 if (width > min_small_width) {
01443 width -= this->panel_widths[1];
01444 arrangable_count = lengthof(arrange_nopanel);
01445 button_count = arrangable_count - 1;
01446 spacer_count = this->spacers - 1;
01447 return arrange_nopanel;
01448 }
01449
01450
01451 width -= this->panel_widths[1];
01452 arrangable_count = lengthof(arrange_switch) / 2;
01453 button_count = arrangable_count - 1;
01454 spacer_count = 0;
01455 return arrange_switch + ((_toolbar_mode == TB_LOWER) ? arrangable_count : 0);
01456 }
01457 };
01458
01459
01460
01461 typedef CallBackFunction ToolbarButtonProc(Window *w);
01462
01463 static ToolbarButtonProc * const _toolbar_button_procs[] = {
01464 ToolbarPauseClick,
01465 ToolbarFastForwardClick,
01466 ToolbarOptionsClick,
01467 ToolbarSaveClick,
01468 ToolbarMapClick,
01469 ToolbarTownClick,
01470 ToolbarSubsidiesClick,
01471 ToolbarStationsClick,
01472 ToolbarFinancesClick,
01473 ToolbarCompaniesClick,
01474 ToolbarGraphsClick,
01475 ToolbarLeagueClick,
01476 ToolbarIndustryClick,
01477 ToolbarTrainClick,
01478 ToolbarRoadClick,
01479 ToolbarShipClick,
01480 ToolbarAirClick,
01481 ToolbarZoomInClick,
01482 ToolbarZoomOutClick,
01483 ToolbarBuildRailClick,
01484 ToolbarBuildRoadClick,
01485 ToolbarBuildWaterClick,
01486 ToolbarBuildAirClick,
01487 ToolbarForestClick,
01488 ToolbarMusicClick,
01489 ToolbarNewspaperClick,
01490 ToolbarHelpClick,
01491 ToolbarSwitchClick,
01492 };
01493
01494 enum MainToolbarHotkeys {
01495 MTHK_PAUSE,
01496 MTHK_FASTFORWARD,
01497 MTHK_SETTINGS,
01498 MTHK_SAVEGAME,
01499 MTHK_LOADGAME,
01500 MTHK_SMALLMAP,
01501 MTHK_TOWNDIRECTORY,
01502 MTHK_SUBSIDIES,
01503 MTHK_STATIONS,
01504 MTHK_FINANCES,
01505 MTHK_COMPANIES,
01506 MTHK_GRAPHS,
01507 MTHK_LEAGUE,
01508 MTHK_INDUSTRIES,
01509 MTHK_TRAIN_LIST,
01510 MTHK_ROADVEH_LIST,
01511 MTHK_SHIP_LIST,
01512 MTHK_AIRCRAFT_LIST,
01513 MTHK_ZOOM_IN,
01514 MTHK_ZOOM_OUT,
01515 MTHK_BUILD_RAIL,
01516 MTHK_BUILD_ROAD,
01517 MTHK_BUILD_DOCKS,
01518 MTHK_BUILD_AIRPORT,
01519 MTHK_BUILD_TREES,
01520 MTHK_MUSIC,
01521 MTHK_AI_DEBUG,
01522 MTHK_SMALL_SCREENSHOT,
01523 MTHK_ZOOMEDIN_SCREENSHOT,
01524 MTHK_DEFAULTZOOM_SCREENSHOT,
01525 MTHK_GIANT_SCREENSHOT,
01526 MTHK_CHEATS,
01527 MTHK_TERRAFORM,
01528 MTHK_EXTRA_VIEWPORT,
01529 MTHK_CLIENT_LIST,
01530 MTHK_SIGN_LIST,
01531 };
01532
01534 struct MainToolbarWindow : Window {
01535 CallBackFunction last_started_action;
01536
01537 MainToolbarWindow(const WindowDesc *desc) : Window()
01538 {
01539 this->InitNested(desc, 0);
01540
01541 this->last_started_action = CBF_NONE;
01542 CLRBITS(this->flags, WF_WHITE_BORDER);
01543 this->SetWidgetDisabledState(WID_TN_PAUSE, _networking && !_network_server);
01544 this->SetWidgetDisabledState(WID_TN_FAST_FORWARD, _networking);
01545 PositionMainToolbar(this);
01546 DoZoomInOutWindow(ZOOM_NONE, this);
01547 }
01548
01549 virtual void OnPaint()
01550 {
01551
01552
01553
01554 this->SetWidgetsDisabledState(_local_company == COMPANY_SPECTATOR, WID_TN_RAILS, WID_TN_ROADS, WID_TN_WATER, WID_TN_AIR, WID_TN_LANDSCAPE, WIDGET_LIST_END);
01555
01556 this->SetWidgetsDisabledState(Company::GetNumItems() == 0, WID_TN_STATIONS, WID_TN_FINANCES, WID_TN_TRAINS, WID_TN_ROADVEHS, WID_TN_SHIPS, WID_TN_AIRCRAFTS, WIDGET_LIST_END);
01557
01558 this->SetWidgetDisabledState(WID_TN_RAILS, !CanBuildVehicleInfrastructure(VEH_TRAIN));
01559 this->SetWidgetDisabledState(WID_TN_AIR, !CanBuildVehicleInfrastructure(VEH_AIRCRAFT));
01560
01561 this->DrawWidgets();
01562 }
01563
01564 virtual void OnClick(Point pt, int widget, int click_count)
01565 {
01566 if (_game_mode != GM_MENU && !this->IsWidgetDisabled(widget)) _toolbar_button_procs[widget](this);
01567 }
01568
01569 virtual void OnDropdownSelect(int widget, int index)
01570 {
01571 CallBackFunction cbf = _menu_clicked_procs[widget](index);
01572 if (cbf != CBF_NONE) this->last_started_action = cbf;
01573 }
01574
01575 virtual EventState OnKeyPress(uint16 key, uint16 keycode)
01576 {
01577 switch (CheckHotkeyMatch(maintoolbar_hotkeys, keycode, this)) {
01578 case MTHK_PAUSE: ToolbarPauseClick(this); break;
01579 case MTHK_FASTFORWARD: ToolbarFastForwardClick(this); break;
01580 case MTHK_SETTINGS: ShowGameOptions(); break;
01581 case MTHK_SAVEGAME: MenuClickSaveLoad(); break;
01582 case MTHK_LOADGAME: ShowSaveLoadDialog(SLD_LOAD_GAME); break;
01583 case MTHK_SMALLMAP: ShowSmallMap(); break;
01584 case MTHK_TOWNDIRECTORY: ShowTownDirectory(); break;
01585 case MTHK_SUBSIDIES: ShowSubsidiesList(); break;
01586 case MTHK_STATIONS: ShowCompanyStations(_local_company); break;
01587 case MTHK_FINANCES: ShowCompanyFinances(_local_company); break;
01588 case MTHK_COMPANIES: ShowCompany(_local_company); break;
01589 case MTHK_GRAPHS: ShowOperatingProfitGraph(); break;
01590 case MTHK_LEAGUE: ShowCompanyLeagueTable(); break;
01591 case MTHK_INDUSTRIES: ShowBuildIndustryWindow(); break;
01592 case MTHK_TRAIN_LIST: ShowVehicleListWindow(_local_company, VEH_TRAIN); break;
01593 case MTHK_ROADVEH_LIST: ShowVehicleListWindow(_local_company, VEH_ROAD); break;
01594 case MTHK_SHIP_LIST: ShowVehicleListWindow(_local_company, VEH_SHIP); break;
01595 case MTHK_AIRCRAFT_LIST: ShowVehicleListWindow(_local_company, VEH_AIRCRAFT); break;
01596 case MTHK_ZOOM_IN: ToolbarZoomInClick(this); break;
01597 case MTHK_ZOOM_OUT: ToolbarZoomOutClick(this); break;
01598 case MTHK_BUILD_RAIL: if (CanBuildVehicleInfrastructure(VEH_TRAIN)) ShowBuildRailToolbar(_last_built_railtype); break;
01599 case MTHK_BUILD_ROAD: ShowBuildRoadToolbar(_last_built_roadtype); break;
01600 case MTHK_BUILD_DOCKS: ShowBuildDocksToolbar(); break;
01601 case MTHK_BUILD_AIRPORT: if (CanBuildVehicleInfrastructure(VEH_AIRCRAFT)) ShowBuildAirToolbar(); break;
01602 case MTHK_BUILD_TREES: ShowBuildTreesToolbar(); break;
01603 case MTHK_MUSIC: ShowMusicWindow(); break;
01604 case MTHK_AI_DEBUG: ShowAIDebugWindow(); break;
01605 case MTHK_SMALL_SCREENSHOT: MenuClickSmallScreenshot(); break;
01606 case MTHK_ZOOMEDIN_SCREENSHOT: MenuClickZoomedInScreenshot(); break;
01607 case MTHK_DEFAULTZOOM_SCREENSHOT: MenuClickDefaultZoomScreenshot(); break;
01608 case MTHK_GIANT_SCREENSHOT: MenuClickWorldScreenshot(); break;
01609 case MTHK_CHEATS: if (!_networking) ShowCheatWindow(); break;
01610 case MTHK_TERRAFORM: ShowTerraformToolbar(); break;
01611 case MTHK_EXTRA_VIEWPORT: ShowExtraViewPortWindowForTileUnderCursor(); break;
01612 #ifdef ENABLE_NETWORK
01613 case MTHK_CLIENT_LIST: if (_networking) ShowClientList(); break;
01614 #endif
01615 case MTHK_SIGN_LIST: ShowSignList(); break;
01616 default: return ES_NOT_HANDLED;
01617 }
01618 return ES_HANDLED;
01619 }
01620
01621 virtual void OnPlaceObject(Point pt, TileIndex tile)
01622 {
01623 switch (this->last_started_action) {
01624 case CBF_PLACE_SIGN:
01625 PlaceProc_Sign(tile);
01626 break;
01627
01628 case CBF_PLACE_LANDINFO:
01629 ShowLandInfo(tile);
01630 break;
01631
01632 default: NOT_REACHED();
01633 }
01634 }
01635
01636 virtual void OnTick()
01637 {
01638 if (this->IsWidgetLowered(WID_TN_PAUSE) != !!_pause_mode) {
01639 this->ToggleWidgetLoweredState(WID_TN_PAUSE);
01640 this->SetWidgetDirty(WID_TN_PAUSE);
01641 }
01642
01643 if (this->IsWidgetLowered(WID_TN_FAST_FORWARD) != !!_fast_forward) {
01644 this->ToggleWidgetLoweredState(WID_TN_FAST_FORWARD);
01645 this->SetWidgetDirty(WID_TN_FAST_FORWARD);
01646 }
01647 }
01648
01649 virtual void OnTimeout()
01650 {
01651
01652
01653 for (uint i = WID_TN_SETTINGS; i < WID_TN_SWITCH_BAR; i++) {
01654 if (this->IsWidgetLowered(i)) {
01655 this->RaiseWidget(i);
01656 this->SetWidgetDirty(i);
01657 }
01658 }
01659 }
01660
01666 virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
01667 {
01668 if (!gui_scope) return;
01669 if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, WID_TN_ZOOM_IN, WID_TN_ZOOM_OUT);
01670 }
01671
01672 static Hotkey<MainToolbarWindow> maintoolbar_hotkeys[];
01673 };
01674
01675 const uint16 _maintoolbar_pause_keys[] = {WKC_F1, WKC_PAUSE, 0};
01676 const uint16 _maintoolbar_zoomin_keys[] = {WKC_NUM_PLUS, WKC_EQUALS, WKC_SHIFT | WKC_EQUALS, WKC_SHIFT | WKC_F5, 0};
01677 const uint16 _maintoolbar_zoomout_keys[] = {WKC_NUM_MINUS, WKC_MINUS, WKC_SHIFT | WKC_MINUS, WKC_SHIFT | WKC_F6, 0};
01678 const uint16 _maintoolbar_smallmap_keys[] = {WKC_F4, 'M', 0};
01679
01680 Hotkey<MainToolbarWindow> MainToolbarWindow::maintoolbar_hotkeys[] = {
01681 Hotkey<MainToolbarWindow>(_maintoolbar_pause_keys, "pause", MTHK_PAUSE),
01682 Hotkey<MainToolbarWindow>((uint16)0, "fastforward", MTHK_FASTFORWARD),
01683 Hotkey<MainToolbarWindow>(WKC_F2, "settings", MTHK_SETTINGS),
01684 Hotkey<MainToolbarWindow>(WKC_F3, "saveload", MTHK_SAVEGAME),
01685 Hotkey<MainToolbarWindow>((uint16)0, "load_game", MTHK_LOADGAME),
01686 Hotkey<MainToolbarWindow>(_maintoolbar_smallmap_keys, "smallmap", MTHK_SMALLMAP),
01687 Hotkey<MainToolbarWindow>(WKC_F5, "town_list", MTHK_TOWNDIRECTORY),
01688 Hotkey<MainToolbarWindow>(WKC_F6, "subsidies", MTHK_SUBSIDIES),
01689 Hotkey<MainToolbarWindow>(WKC_F7, "station_list", MTHK_STATIONS),
01690 Hotkey<MainToolbarWindow>(WKC_F8, "finances", MTHK_FINANCES),
01691 Hotkey<MainToolbarWindow>(WKC_F9, "companies", MTHK_COMPANIES),
01692 Hotkey<MainToolbarWindow>(WKC_F10, "graphs", MTHK_GRAPHS),
01693 Hotkey<MainToolbarWindow>(WKC_F11, "league", MTHK_LEAGUE),
01694 Hotkey<MainToolbarWindow>(WKC_F12, "industry_list", MTHK_INDUSTRIES),
01695 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F1, "train_list", MTHK_TRAIN_LIST),
01696 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F2, "roadveh_list", MTHK_ROADVEH_LIST),
01697 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F3, "ship_list", MTHK_SHIP_LIST),
01698 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F4, "aircraft_list", MTHK_AIRCRAFT_LIST),
01699 Hotkey<MainToolbarWindow>(_maintoolbar_zoomin_keys, "zoomin", MTHK_ZOOM_IN),
01700 Hotkey<MainToolbarWindow>(_maintoolbar_zoomout_keys, "zoomout", MTHK_ZOOM_OUT),
01701 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F7, "build_rail", MTHK_BUILD_RAIL),
01702 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F8, "build_road", MTHK_BUILD_ROAD),
01703 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F9, "build_docks", MTHK_BUILD_DOCKS),
01704 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F10, "build_airport", MTHK_BUILD_AIRPORT),
01705 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F11, "build_trees", MTHK_BUILD_TREES),
01706 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F12, "music", MTHK_MUSIC),
01707 Hotkey<MainToolbarWindow>((uint16)0, "ai_debug", MTHK_AI_DEBUG),
01708 Hotkey<MainToolbarWindow>(WKC_CTRL | 'S', "small_screenshot", MTHK_SMALL_SCREENSHOT),
01709 Hotkey<MainToolbarWindow>(WKC_CTRL | 'P', "zoomedin_screenshot", MTHK_ZOOMEDIN_SCREENSHOT),
01710 Hotkey<MainToolbarWindow>(WKC_CTRL | 'D', "defaultzoom_screenshot", MTHK_DEFAULTZOOM_SCREENSHOT),
01711 Hotkey<MainToolbarWindow>((uint16)0, "giant_screenshot", MTHK_GIANT_SCREENSHOT),
01712 Hotkey<MainToolbarWindow>(WKC_CTRL | WKC_ALT | 'C', "cheats", MTHK_CHEATS),
01713 Hotkey<MainToolbarWindow>('L', "terraform", MTHK_TERRAFORM),
01714 Hotkey<MainToolbarWindow>('V', "extra_viewport", MTHK_EXTRA_VIEWPORT),
01715 #ifdef ENABLE_NETWORK
01716 Hotkey<MainToolbarWindow>((uint16)0, "client_list", MTHK_CLIENT_LIST),
01717 #endif
01718 Hotkey<MainToolbarWindow>((uint16)0, "sign_list", MTHK_SIGN_LIST),
01719 HOTKEY_LIST_END(MainToolbarWindow)
01720 };
01721 Hotkey<MainToolbarWindow> *_maintoolbar_hotkeys = MainToolbarWindow::maintoolbar_hotkeys;
01722
01723 static NWidgetBase *MakeMainToolbar(int *biggest_index)
01724 {
01726 static const SpriteID toolbar_button_sprites[] = {
01727 SPR_IMG_PAUSE,
01728 SPR_IMG_FASTFORWARD,
01729 SPR_IMG_SETTINGS,
01730 SPR_IMG_SAVE,
01731 SPR_IMG_SMALLMAP,
01732 SPR_IMG_TOWN,
01733 SPR_IMG_SUBSIDIES,
01734 SPR_IMG_COMPANY_LIST,
01735 SPR_IMG_COMPANY_FINANCE,
01736 SPR_IMG_COMPANY_GENERAL,
01737 SPR_IMG_GRAPHS,
01738 SPR_IMG_COMPANY_LEAGUE,
01739 SPR_IMG_INDUSTRY,
01740 SPR_IMG_TRAINLIST,
01741 SPR_IMG_TRUCKLIST,
01742 SPR_IMG_SHIPLIST,
01743 SPR_IMG_AIRPLANESLIST,
01744 SPR_IMG_ZOOMIN,
01745 SPR_IMG_ZOOMOUT,
01746 SPR_IMG_BUILDRAIL,
01747 SPR_IMG_BUILDROAD,
01748 SPR_IMG_BUILDWATER,
01749 SPR_IMG_BUILDAIR,
01750 SPR_IMG_LANDSCAPING,
01751 SPR_IMG_MUSIC,
01752 SPR_IMG_MESSAGES,
01753 SPR_IMG_QUERY,
01754 SPR_IMG_SWITCH_TOOLBAR,
01755 };
01756
01757 NWidgetMainToolbarContainer *hor = new NWidgetMainToolbarContainer();
01758 for (uint i = 0; i < WID_TN_END; i++) {
01759 switch (i) {
01760 case 4: case 8: case 13: case 17: case 19: case 24: hor->Add(new NWidgetSpacer(0, 0)); break;
01761 }
01762 hor->Add(new NWidgetLeaf(i == WID_TN_SAVE ? WWT_IMGBTN_2 : WWT_IMGBTN, COLOUR_GREY, i, toolbar_button_sprites[i], STR_TOOLBAR_TOOLTIP_PAUSE_GAME + i));
01763 }
01764
01765 *biggest_index = max<int>(*biggest_index, WID_TN_SWITCH_BAR);
01766 return hor;
01767 }
01768
01769 static const NWidgetPart _nested_toolbar_normal_widgets[] = {
01770 NWidgetFunction(MakeMainToolbar),
01771 };
01772
01773 static WindowDesc _toolb_normal_desc(
01774 WDP_MANUAL, 640, 22,
01775 WC_MAIN_TOOLBAR, WC_NONE,
01776 WDF_NO_FOCUS,
01777 _nested_toolbar_normal_widgets, lengthof(_nested_toolbar_normal_widgets)
01778 );
01779
01780
01781
01782
01783 static ToolbarButtonProc * const _scen_toolbar_button_procs[] = {
01784 ToolbarPauseClick,
01785 ToolbarFastForwardClick,
01786 ToolbarOptionsClick,
01787 ToolbarScenSaveOrLoad,
01788 ToolbarBtn_NULL,
01789 ToolbarScenDatePanel,
01790 ToolbarScenDateBackward,
01791 ToolbarScenDateForward,
01792 ToolbarScenMapTownDir,
01793 ToolbarZoomInClick,
01794 ToolbarZoomOutClick,
01795 ToolbarScenGenLand,
01796 ToolbarScenGenTown,
01797 ToolbarScenGenIndustry,
01798 ToolbarScenBuildRoad,
01799 ToolbarScenBuildDocks,
01800 ToolbarScenPlantTrees,
01801 ToolbarScenPlaceSign,
01802 ToolbarBtn_NULL,
01803 NULL,
01804 NULL,
01805 NULL,
01806 NULL,
01807 NULL,
01808 ToolbarMusicClick,
01809 NULL,
01810 ToolbarHelpClick,
01811 ToolbarSwitchClick,
01812 };
01813
01814 enum MainToolbarEditorHotkeys {
01815 MTEHK_PAUSE,
01816 MTEHK_FASTFORWARD,
01817 MTEHK_SETTINGS,
01818 MTEHK_SAVEGAME,
01819 MTEHK_GENLAND,
01820 MTEHK_GENTOWN,
01821 MTEHK_GENINDUSTRY,
01822 MTEHK_BUILD_ROAD,
01823 MTEHK_BUILD_DOCKS,
01824 MTEHK_BUILD_TREES,
01825 MTEHK_SIGN,
01826 MTEHK_MUSIC,
01827 MTEHK_LANDINFO,
01828 MTEHK_SMALL_SCREENSHOT,
01829 MTEHK_ZOOMEDIN_SCREENSHOT,
01830 MTEHK_DEFAULTZOOM_SCREENSHOT,
01831 MTEHK_GIANT_SCREENSHOT,
01832 MTEHK_ZOOM_IN,
01833 MTEHK_ZOOM_OUT,
01834 MTEHK_TERRAFORM,
01835 MTEHK_SMALLMAP,
01836 MTEHK_EXTRA_VIEWPORT,
01837 };
01838
01839 struct ScenarioEditorToolbarWindow : Window {
01840 CallBackFunction last_started_action;
01841
01842 ScenarioEditorToolbarWindow(const WindowDesc *desc) : Window()
01843 {
01844 this->InitNested(desc, 0);
01845
01846 this->last_started_action = CBF_NONE;
01847 CLRBITS(this->flags, WF_WHITE_BORDER);
01848 PositionMainToolbar(this);
01849 DoZoomInOutWindow(ZOOM_NONE, this);
01850 }
01851
01852 virtual void OnPaint()
01853 {
01854 this->SetWidgetDisabledState(WID_TE_DATE_BACKWARD, _settings_game.game_creation.starting_year <= MIN_YEAR);
01855 this->SetWidgetDisabledState(WID_TE_DATE_FORWARD, _settings_game.game_creation.starting_year >= MAX_YEAR);
01856
01857 this->DrawWidgets();
01858 }
01859
01860 virtual void DrawWidget(const Rect &r, int widget) const
01861 {
01862 switch (widget) {
01863 case WID_TE_DATE:
01864 SetDParam(0, ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
01865 DrawString(r.left, r.right, (this->height - FONT_HEIGHT_NORMAL) / 2, STR_WHITE_DATE_LONG, TC_FROMSTRING, SA_HOR_CENTER);
01866 break;
01867
01868 case WID_TE_SPACER: {
01869 int height = r.bottom - r.top;
01870 if (height > 2 * FONT_HEIGHT_NORMAL) {
01871 DrawString(r.left, r.right, (height + 1) / 2 - FONT_HEIGHT_NORMAL, STR_SCENEDIT_TOOLBAR_OPENTTD, TC_FROMSTRING, SA_HOR_CENTER);
01872 DrawString(r.left, r.right, (height + 1) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_HOR_CENTER);
01873 } else {
01874 DrawString(r.left, r.right, (height - FONT_HEIGHT_NORMAL) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_HOR_CENTER);
01875 }
01876 break;
01877 }
01878 }
01879 }
01880
01881 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
01882 {
01883 switch (widget) {
01884 case WID_TE_SPACER:
01885 size->width = max(GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_OPENTTD).width, GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR).width) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
01886 break;
01887
01888 case WID_TE_DATE:
01889 SetDParam(0, ConvertYMDToDate(MAX_YEAR, 0, 1));
01890 *size = GetStringBoundingBox(STR_WHITE_DATE_LONG);
01891 size->height = max(size->height, GetSpriteSize(SPR_IMG_SAVE).height + WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM);
01892 break;
01893 }
01894 }
01895
01896 virtual void OnClick(Point pt, int widget, int click_count)
01897 {
01898 if (_game_mode == GM_MENU) return;
01899 CallBackFunction cbf = _scen_toolbar_button_procs[widget](this);
01900 if (cbf != CBF_NONE) this->last_started_action = cbf;
01901 }
01902
01903 virtual void OnDropdownSelect(int widget, int index)
01904 {
01905
01906
01907 if (widget == WID_TE_SMALL_MAP) widget = WID_TN_SMALL_MAP;
01908 CallBackFunction cbf = _menu_clicked_procs[widget](index);
01909 if (cbf != CBF_NONE) this->last_started_action = cbf;
01910 SndPlayFx(SND_15_BEEP);
01911 }
01912
01913 virtual EventState OnKeyPress(uint16 key, uint16 keycode)
01914 {
01915 CallBackFunction cbf = CBF_NONE;
01916 switch (CheckHotkeyMatch(scenedit_maintoolbar_hotkeys, keycode, this)) {
01917 case MTEHK_PAUSE: ToolbarPauseClick(this); break;
01918 case MTEHK_FASTFORWARD: ToolbarFastForwardClick(this); break;
01919 case MTEHK_SETTINGS: ShowGameOptions(); break;
01920 case MTEHK_SAVEGAME: MenuClickSaveLoad(); break;
01921 case MTEHK_GENLAND: ToolbarScenGenLand(this); break;
01922 case MTEHK_GENTOWN: ToolbarScenGenTown(this); break;
01923 case MTEHK_GENINDUSTRY: ToolbarScenGenIndustry(this); break;
01924 case MTEHK_BUILD_ROAD: ToolbarScenBuildRoad(this); break;
01925 case MTEHK_BUILD_DOCKS: ToolbarScenBuildDocks(this); break;
01926 case MTEHK_BUILD_TREES: ToolbarScenPlantTrees(this); break;
01927 case MTEHK_SIGN: cbf = ToolbarScenPlaceSign(this); break;
01928 case MTEHK_MUSIC: ShowMusicWindow(); break;
01929 case MTEHK_LANDINFO: cbf = PlaceLandBlockInfo(); break;
01930 case MTEHK_SMALL_SCREENSHOT: MenuClickSmallScreenshot(); break;
01931 case MTEHK_ZOOMEDIN_SCREENSHOT: MenuClickZoomedInScreenshot(); break;
01932 case MTEHK_DEFAULTZOOM_SCREENSHOT: MenuClickDefaultZoomScreenshot(); break;
01933 case MTEHK_GIANT_SCREENSHOT: MenuClickWorldScreenshot(); break;
01934 case MTEHK_ZOOM_IN: ToolbarZoomInClick(this); break;
01935 case MTEHK_ZOOM_OUT: ToolbarZoomOutClick(this); break;
01936 case MTEHK_TERRAFORM: ShowEditorTerraformToolbar(); break;
01937 case MTEHK_SMALLMAP: ShowSmallMap(); break;
01938 case MTEHK_EXTRA_VIEWPORT: ShowExtraViewPortWindowForTileUnderCursor(); break;
01939 default: return ES_NOT_HANDLED;
01940 }
01941 if (cbf != CBF_NONE) this->last_started_action = cbf;
01942 return ES_HANDLED;
01943 }
01944
01945 virtual void OnPlaceObject(Point pt, TileIndex tile)
01946 {
01947 switch (this->last_started_action) {
01948 case CBF_PLACE_SIGN:
01949 PlaceProc_Sign(tile);
01950 break;
01951
01952 case CBF_PLACE_LANDINFO:
01953 ShowLandInfo(tile);
01954 break;
01955
01956 default: NOT_REACHED();
01957 }
01958 }
01959
01960 virtual void OnTimeout()
01961 {
01962 this->SetWidgetsLoweredState(false, WID_TE_DATE_BACKWARD, WID_TE_DATE_FORWARD, WIDGET_LIST_END);
01963 this->SetWidgetDirty(WID_TE_DATE_BACKWARD);
01964 this->SetWidgetDirty(WID_TE_DATE_FORWARD);
01965 }
01966
01967 virtual void OnTick()
01968 {
01969 if (this->IsWidgetLowered(WID_TE_PAUSE) != !!_pause_mode) {
01970 this->ToggleWidgetLoweredState(WID_TE_PAUSE);
01971 this->SetDirty();
01972 }
01973
01974 if (this->IsWidgetLowered(WID_TE_FAST_FORWARD) != !!_fast_forward) {
01975 this->ToggleWidgetLoweredState(WID_TE_FAST_FORWARD);
01976 this->SetDirty();
01977 }
01978 }
01979
01985 virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
01986 {
01987 if (!gui_scope) return;
01988 if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, WID_TE_ZOOM_IN, WID_TE_ZOOM_OUT);
01989 }
01990
01991 virtual void OnQueryTextFinished(char *str)
01992 {
01993
01994 if (str == NULL) return;
01995
01996 int32 value;
01997 if (!StrEmpty(str)) {
01998 value = atoi(str);
01999 } else {
02000
02001 value = DEF_START_YEAR;
02002 }
02003 _settings_game.game_creation.starting_year = Clamp(value, MIN_YEAR, MAX_YEAR);
02004 SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0);
02005
02006 this->SetDirty();
02007 }
02008
02009 static Hotkey<ScenarioEditorToolbarWindow> scenedit_maintoolbar_hotkeys[];
02010 };
02011
02012 Hotkey<ScenarioEditorToolbarWindow> ScenarioEditorToolbarWindow::scenedit_maintoolbar_hotkeys[] = {
02013 Hotkey<ScenarioEditorToolbarWindow>(_maintoolbar_pause_keys, "pause", MTEHK_PAUSE),
02014 Hotkey<ScenarioEditorToolbarWindow>((uint16)0, "fastforward", MTEHK_FASTFORWARD),
02015 Hotkey<ScenarioEditorToolbarWindow>(WKC_F2, "settings", MTEHK_SETTINGS),
02016 Hotkey<ScenarioEditorToolbarWindow>(WKC_F3, "saveload", MTEHK_SAVEGAME),
02017 Hotkey<ScenarioEditorToolbarWindow>(WKC_F4, "gen_land", MTEHK_GENLAND),
02018 Hotkey<ScenarioEditorToolbarWindow>(WKC_F5, "gen_town", MTEHK_GENTOWN),
02019 Hotkey<ScenarioEditorToolbarWindow>(WKC_F6, "gen_industry", MTEHK_GENINDUSTRY),
02020 Hotkey<ScenarioEditorToolbarWindow>(WKC_F7, "build_road", MTEHK_BUILD_ROAD),
02021 Hotkey<ScenarioEditorToolbarWindow>(WKC_F8, "build_docks", MTEHK_BUILD_DOCKS),
02022 Hotkey<ScenarioEditorToolbarWindow>(WKC_F9, "build_trees", MTEHK_BUILD_TREES),
02023 Hotkey<ScenarioEditorToolbarWindow>(WKC_F10, "build_sign", MTEHK_SIGN),
02024 Hotkey<ScenarioEditorToolbarWindow>(WKC_F11, "music", MTEHK_MUSIC),
02025 Hotkey<ScenarioEditorToolbarWindow>(WKC_F12, "land_info", MTEHK_LANDINFO),
02026 Hotkey<ScenarioEditorToolbarWindow>(WKC_CTRL | 'S', "small_screenshot", MTEHK_SMALL_SCREENSHOT),
02027 Hotkey<ScenarioEditorToolbarWindow>(WKC_CTRL | 'P', "zoomedin_screenshot", MTEHK_ZOOMEDIN_SCREENSHOT),
02028 Hotkey<ScenarioEditorToolbarWindow>(WKC_CTRL | 'D', "defaultzoom_screenshot", MTEHK_DEFAULTZOOM_SCREENSHOT),
02029 Hotkey<ScenarioEditorToolbarWindow>((uint16)0, "giant_screenshot", MTEHK_GIANT_SCREENSHOT),
02030 Hotkey<ScenarioEditorToolbarWindow>(_maintoolbar_zoomin_keys, "zoomin", MTEHK_ZOOM_IN),
02031 Hotkey<ScenarioEditorToolbarWindow>(_maintoolbar_zoomout_keys, "zoomout", MTEHK_ZOOM_OUT),
02032 Hotkey<ScenarioEditorToolbarWindow>('L', "terraform", MTEHK_TERRAFORM),
02033 Hotkey<ScenarioEditorToolbarWindow>('M', "smallmap", MTEHK_SMALLMAP),
02034 Hotkey<ScenarioEditorToolbarWindow>('V', "extra_viewport", MTEHK_EXTRA_VIEWPORT),
02035 HOTKEY_LIST_END(ScenarioEditorToolbarWindow)
02036 };
02037 Hotkey<ScenarioEditorToolbarWindow> *_scenedit_maintoolbar_hotkeys = ScenarioEditorToolbarWindow::scenedit_maintoolbar_hotkeys;
02038
02039 static const NWidgetPart _nested_toolb_scen_inner_widgets[] = {
02040 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_PAUSE), SetDataTip(SPR_IMG_PAUSE, STR_TOOLBAR_TOOLTIP_PAUSE_GAME),
02041 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_FAST_FORWARD), SetDataTip(SPR_IMG_FASTFORWARD, STR_TOOLBAR_TOOLTIP_FORWARD),
02042 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_SETTINGS), SetDataTip(SPR_IMG_SETTINGS, STR_TOOLBAR_TOOLTIP_OPTIONS),
02043 NWidget(WWT_IMGBTN_2, COLOUR_GREY, WID_TE_SAVE), SetDataTip(SPR_IMG_SAVE, STR_SCENEDIT_TOOLBAR_TOOLTIP_SAVE_SCENARIO_LOAD_SCENARIO),
02044 NWidget(NWID_SPACER),
02045 NWidget(WWT_PANEL, COLOUR_GREY, WID_TE_SPACER), EndContainer(),
02046 NWidget(NWID_SPACER),
02047 NWidget(WWT_PANEL, COLOUR_GREY, WID_TE_DATE_PANEL),
02048 NWidget(NWID_HORIZONTAL), SetPIP(3, 2, 3),
02049 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_DATE_BACKWARD), SetDataTip(SPR_ARROW_DOWN, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD),
02050 NWidget(WWT_EMPTY, COLOUR_GREY, WID_TE_DATE), SetDataTip(STR_NULL, STR_SCENEDIT_TOOLBAR_TOOLTIP_SET_DATE),
02051 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_DATE_FORWARD), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD),
02052 EndContainer(),
02053 EndContainer(),
02054 NWidget(NWID_SPACER),
02055 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_SMALL_MAP), SetDataTip(SPR_IMG_SMALLMAP, STR_SCENEDIT_TOOLBAR_TOOLTIP_DISPLAY_MAP_TOWN_DIRECTORY),
02056 NWidget(NWID_SPACER),
02057 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_ZOOM_IN), SetDataTip(SPR_IMG_ZOOMIN, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN),
02058 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_ZOOM_OUT), SetDataTip(SPR_IMG_ZOOMOUT, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT),
02059 NWidget(NWID_SPACER),
02060 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_LAND_GENERATE), SetDataTip(SPR_IMG_LANDSCAPING, STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION),
02061 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_TOWN_GENERATE), SetDataTip(SPR_IMG_TOWN, STR_SCENEDIT_TOOLBAR_TOWN_GENERATION),
02062 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_INDUSTRY), SetDataTip(SPR_IMG_INDUSTRY, STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION),
02063 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_ROADS), SetDataTip(SPR_IMG_BUILDROAD, STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION),
02064 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_WATER), SetDataTip(SPR_IMG_BUILDWATER, STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS),
02065 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_TREES), SetDataTip(SPR_IMG_PLANTTREES, STR_SCENEDIT_TOOLBAR_PLANT_TREES),
02066 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_SIGNS), SetDataTip(SPR_IMG_SIGN, STR_SCENEDIT_TOOLBAR_PLACE_SIGN),
02067 NWidget(NWID_SPACER),
02068 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_MUSIC_SOUND), SetDataTip(SPR_IMG_MUSIC, STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW),
02069 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_HELP), SetDataTip(SPR_IMG_QUERY, STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION),
02070 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_SWITCH_BAR), SetDataTip(SPR_IMG_SWITCH_TOOLBAR, STR_TOOLBAR_TOOLTIP_SWITCH_TOOLBAR),
02071 };
02072
02073 static NWidgetBase *MakeScenarioToolbar(int *biggest_index)
02074 {
02075 return MakeNWidgets(_nested_toolb_scen_inner_widgets, lengthof(_nested_toolb_scen_inner_widgets), biggest_index, new NWidgetScenarioToolbarContainer());
02076 }
02077
02078 static const NWidgetPart _nested_toolb_scen_widgets[] = {
02079 NWidgetFunction(MakeScenarioToolbar),
02080 };
02081
02082 static WindowDesc _toolb_scen_desc(
02083 WDP_MANUAL, 640, 22,
02084 WC_MAIN_TOOLBAR, WC_NONE,
02085 WDF_NO_FOCUS,
02086 _nested_toolb_scen_widgets, lengthof(_nested_toolb_scen_widgets)
02087 );
02088
02090 void AllocateToolbar()
02091 {
02092
02093 _last_built_roadtype = ROADTYPE_ROAD;
02094
02095 if (_game_mode == GM_EDITOR) {
02096 _preferred_toolbar_size = &_toolb_scen_desc.default_width;
02097 new ScenarioEditorToolbarWindow(&_toolb_scen_desc);
02098 } else {
02099 _preferred_toolbar_size = &_toolb_normal_desc.default_width;
02100 new MainToolbarWindow(&_toolb_normal_desc);
02101 }
02102 }