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) ? 1 : 2);
00641 return CBF_NONE;
00642 }
00643
00650 static CallBackFunction MenuClickIndustry(int index)
00651 {
00652 switch (index) {
00653 case 0: ShowIndustryDirectory(); break;
00654 case 1: ShowBuildIndustryWindow(); break;
00655 }
00656 return CBF_NONE;
00657 }
00658
00659
00660
00661 static void ToolbarVehicleClick(Window *w, VehicleType veh)
00662 {
00663 const Vehicle *v;
00664 int dis = ~0;
00665
00666 FOR_ALL_VEHICLES(v) {
00667 if (v->type == veh && v->IsPrimaryVehicle()) ClrBit(dis, v->owner);
00668 }
00669 PopupMainCompanyToolbMenu(w, WID_TN_VEHICLE_START + veh, dis);
00670 }
00671
00672
00673 static CallBackFunction ToolbarTrainClick(Window *w)
00674 {
00675 ToolbarVehicleClick(w, VEH_TRAIN);
00676 return CBF_NONE;
00677 }
00678
00685 static CallBackFunction MenuClickShowTrains(int index)
00686 {
00687 ShowVehicleListWindow((CompanyID)index, VEH_TRAIN);
00688 return CBF_NONE;
00689 }
00690
00691
00692
00693 static CallBackFunction ToolbarRoadClick(Window *w)
00694 {
00695 ToolbarVehicleClick(w, VEH_ROAD);
00696 return CBF_NONE;
00697 }
00698
00705 static CallBackFunction MenuClickShowRoad(int index)
00706 {
00707 ShowVehicleListWindow((CompanyID)index, VEH_ROAD);
00708 return CBF_NONE;
00709 }
00710
00711
00712
00713 static CallBackFunction ToolbarShipClick(Window *w)
00714 {
00715 ToolbarVehicleClick(w, VEH_SHIP);
00716 return CBF_NONE;
00717 }
00718
00725 static CallBackFunction MenuClickShowShips(int index)
00726 {
00727 ShowVehicleListWindow((CompanyID)index, VEH_SHIP);
00728 return CBF_NONE;
00729 }
00730
00731
00732
00733 static CallBackFunction ToolbarAirClick(Window *w)
00734 {
00735 ToolbarVehicleClick(w, VEH_AIRCRAFT);
00736 return CBF_NONE;
00737 }
00738
00745 static CallBackFunction MenuClickShowAir(int index)
00746 {
00747 ShowVehicleListWindow((CompanyID)index, VEH_AIRCRAFT);
00748 return CBF_NONE;
00749 }
00750
00751
00752
00753 static CallBackFunction ToolbarZoomInClick(Window *w)
00754 {
00755 if (DoZoomInOutWindow(ZOOM_IN, FindWindowById(WC_MAIN_WINDOW, 0))) {
00756 w->HandleButtonClick((_game_mode == GM_EDITOR) ? (byte)WID_TE_ZOOM_IN : (byte)WID_TN_ZOOM_IN);
00757 SndPlayFx(SND_15_BEEP);
00758 }
00759 return CBF_NONE;
00760 }
00761
00762
00763
00764 static CallBackFunction ToolbarZoomOutClick(Window *w)
00765 {
00766 if (DoZoomInOutWindow(ZOOM_OUT, FindWindowById(WC_MAIN_WINDOW, 0))) {
00767 w->HandleButtonClick((_game_mode == GM_EDITOR) ? (byte)WID_TE_ZOOM_OUT : (byte)WID_TN_ZOOM_OUT);
00768 SndPlayFx(SND_15_BEEP);
00769 }
00770 return CBF_NONE;
00771 }
00772
00773
00774
00775 static CallBackFunction ToolbarBuildRailClick(Window *w)
00776 {
00777 ShowDropDownList(w, GetRailTypeDropDownList(), _last_built_railtype, WID_TN_RAILS, 140, true, true);
00778 SndPlayFx(SND_15_BEEP);
00779 return CBF_NONE;
00780 }
00781
00788 static CallBackFunction MenuClickBuildRail(int index)
00789 {
00790 _last_built_railtype = (RailType)index;
00791 ShowBuildRailToolbar(_last_built_railtype);
00792 return CBF_NONE;
00793 }
00794
00795
00796
00797 static CallBackFunction ToolbarBuildRoadClick(Window *w)
00798 {
00799 const Company *c = Company::Get(_local_company);
00800 DropDownList *list = new DropDownList();
00801
00802
00803 list->push_back(new DropDownListStringItem(STR_ROAD_MENU_ROAD_CONSTRUCTION, ROADTYPE_ROAD, false));
00804
00805
00806 Engine *e;
00807 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
00808 if (!HasBit(e->info.climates, _settings_game.game_creation.landscape)) continue;
00809 if (!HasBit(e->info.misc_flags, EF_ROAD_TRAM)) continue;
00810
00811 list->push_back(new DropDownListStringItem(STR_ROAD_MENU_TRAM_CONSTRUCTION, ROADTYPE_TRAM, !HasBit(c->avail_roadtypes, ROADTYPE_TRAM)));
00812 break;
00813 }
00814 ShowDropDownList(w, list, _last_built_roadtype, WID_TN_ROADS, 140, true, true);
00815 SndPlayFx(SND_15_BEEP);
00816 return CBF_NONE;
00817 }
00818
00825 static CallBackFunction MenuClickBuildRoad(int index)
00826 {
00827 _last_built_roadtype = (RoadType)index;
00828 ShowBuildRoadToolbar(_last_built_roadtype);
00829 return CBF_NONE;
00830 }
00831
00832
00833
00834 static CallBackFunction ToolbarBuildWaterClick(Window *w)
00835 {
00836 PopupMainToolbMenu(w, WID_TN_WATER, STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION, 1);
00837 return CBF_NONE;
00838 }
00839
00846 static CallBackFunction MenuClickBuildWater(int index)
00847 {
00848 ShowBuildDocksToolbar();
00849 return CBF_NONE;
00850 }
00851
00852
00853
00854 static CallBackFunction ToolbarBuildAirClick(Window *w)
00855 {
00856 PopupMainToolbMenu(w, WID_TN_AIR, STR_AIRCRAFT_MENU_AIRPORT_CONSTRUCTION, 1);
00857 return CBF_NONE;
00858 }
00859
00866 static CallBackFunction MenuClickBuildAir(int index)
00867 {
00868 ShowBuildAirToolbar();
00869 return CBF_NONE;
00870 }
00871
00872
00873
00874 static CallBackFunction ToolbarForestClick(Window *w)
00875 {
00876 PopupMainToolbMenu(w, WID_TN_LANDSCAPE, STR_LANDSCAPING_MENU_LANDSCAPING, 3);
00877 return CBF_NONE;
00878 }
00879
00886 static CallBackFunction MenuClickForest(int index)
00887 {
00888 switch (index) {
00889 case 0: ShowTerraformToolbar(); break;
00890 case 1: ShowBuildTreesToolbar(); break;
00891 case 2: return SelectSignTool();
00892 }
00893 return CBF_NONE;
00894 }
00895
00896
00897
00898 static CallBackFunction ToolbarMusicClick(Window *w)
00899 {
00900 PopupMainToolbMenu(w, WID_TN_MUSIC_SOUND, STR_TOOLBAR_SOUND_MUSIC, 1);
00901 return CBF_NONE;
00902 }
00903
00910 static CallBackFunction MenuClickMusicWindow(int index)
00911 {
00912 ShowMusicWindow();
00913 return CBF_NONE;
00914 }
00915
00916
00917
00918 static CallBackFunction ToolbarNewspaperClick(Window *w)
00919 {
00920 PopupMainToolbMenu(w, WID_TN_MESSAGES, STR_NEWS_MENU_LAST_MESSAGE_NEWS_REPORT, 3);
00921 return CBF_NONE;
00922 }
00923
00930 static CallBackFunction MenuClickNewspaper(int index)
00931 {
00932 switch (index) {
00933 case 0: ShowLastNewsMessage(); break;
00934 case 1: ShowMessageOptions(); break;
00935 case 2: ShowMessageHistory(); break;
00936 }
00937 return CBF_NONE;
00938 }
00939
00940
00941
00942 static CallBackFunction PlaceLandBlockInfo()
00943 {
00944 if (_cursor.sprite == SPR_CURSOR_QUERY) {
00945 ResetObjectToPlace();
00946 return CBF_NONE;
00947 } else {
00948 SetObjectToPlace(SPR_CURSOR_QUERY, PAL_NONE, HT_RECT, WC_MAIN_TOOLBAR, 0);
00949 return CBF_PLACE_LANDINFO;
00950 }
00951 }
00952
00953 static CallBackFunction ToolbarHelpClick(Window *w)
00954 {
00955 PopupMainToolbMenu(w, WID_TN_HELP, STR_ABOUT_MENU_LAND_BLOCK_INFO, _settings_client.gui.newgrf_developer_tools ? 12 : 9);
00956 return CBF_NONE;
00957 }
00958
00959 static void MenuClickSmallScreenshot()
00960 {
00961 MakeScreenshot(SC_VIEWPORT, NULL);
00962 }
00963
00964 static void MenuClickZoomedInScreenshot()
00965 {
00966 MakeScreenshot(SC_ZOOMEDIN, NULL);
00967 }
00968
00969 static void MenuClickDefaultZoomScreenshot()
00970 {
00971 MakeScreenshot(SC_DEFAULTZOOM, NULL);
00972 }
00973
00974 static void MenuClickWorldScreenshot()
00975 {
00976 MakeScreenshot(SC_WORLD, NULL);
00977 }
00978
00986 void ToggleBoundingBoxes()
00987 {
00988 extern bool _draw_bounding_boxes;
00989
00990 if (_settings_client.gui.newgrf_developer_tools || _draw_bounding_boxes) {
00991 _draw_bounding_boxes = !_draw_bounding_boxes;
00992 MarkWholeScreenDirty();
00993 }
00994 }
00995
01003 void ToggleDirtyBlocks()
01004 {
01005 extern bool _draw_dirty_blocks;
01006
01007 if (_settings_client.gui.newgrf_developer_tools || _draw_dirty_blocks) {
01008 _draw_dirty_blocks = !_draw_dirty_blocks;
01009 MarkWholeScreenDirty();
01010 }
01011 }
01012
01018 static CallBackFunction MenuClickHelp(int index)
01019 {
01020 switch (index) {
01021 case 0: return PlaceLandBlockInfo();
01022 case 2: IConsoleSwitch(); break;
01023 case 3: ShowAIDebugWindow(); break;
01024 case 4: MenuClickSmallScreenshot(); break;
01025 case 5: MenuClickZoomedInScreenshot(); break;
01026 case 6: MenuClickDefaultZoomScreenshot(); break;
01027 case 7: MenuClickWorldScreenshot(); break;
01028 case 8: ShowAboutWindow(); break;
01029 case 9: ShowSpriteAlignerWindow(); break;
01030 case 10: ToggleBoundingBoxes(); break;
01031 case 11: ToggleDirtyBlocks(); break;
01032 }
01033 return CBF_NONE;
01034 }
01035
01036
01037
01038 static CallBackFunction ToolbarSwitchClick(Window *w)
01039 {
01040 if (_toolbar_mode != TB_LOWER) {
01041 _toolbar_mode = TB_LOWER;
01042 } else {
01043 _toolbar_mode = TB_UPPER;
01044 }
01045
01046 w->ReInit();
01047 w->SetWidgetLoweredState(WID_TN_SWITCH_BAR, _toolbar_mode == TB_LOWER);
01048 SndPlayFx(SND_15_BEEP);
01049 return CBF_NONE;
01050 }
01051
01052
01053
01057 static CallBackFunction ToolbarScenDatePanel(Window *w)
01058 {
01059 SetDParam(0, _settings_game.game_creation.starting_year);
01060 ShowQueryString(STR_JUST_INT, STR_MAPGEN_START_DATE_QUERY_CAPT, 8, w, CS_NUMERAL, QSF_ENABLE_DEFAULT);
01061 _left_button_clicked = false;
01062 return CBF_NONE;
01063 }
01064
01065 static CallBackFunction ToolbarScenDateBackward(Window *w)
01066 {
01067
01068 if (!(w->flags & WF_TIMEOUT) || w->timeout_timer <= 1) {
01069 w->HandleButtonClick(WID_TE_DATE_BACKWARD);
01070 w->SetDirty();
01071
01072 _settings_game.game_creation.starting_year = Clamp(_settings_game.game_creation.starting_year - 1, MIN_YEAR, MAX_YEAR);
01073 SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0);
01074 }
01075 _left_button_clicked = false;
01076 return CBF_NONE;
01077 }
01078
01079 static CallBackFunction ToolbarScenDateForward(Window *w)
01080 {
01081
01082 if (!(w->flags & WF_TIMEOUT) || w->timeout_timer <= 1) {
01083 w->HandleButtonClick(WID_TE_DATE_FORWARD);
01084 w->SetDirty();
01085
01086 _settings_game.game_creation.starting_year = Clamp(_settings_game.game_creation.starting_year + 1, MIN_YEAR, MAX_YEAR);
01087 SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0);
01088 }
01089 _left_button_clicked = false;
01090 return CBF_NONE;
01091 }
01092
01093 static CallBackFunction ToolbarScenGenLand(Window *w)
01094 {
01095 w->HandleButtonClick(WID_TE_LAND_GENERATE);
01096 SndPlayFx(SND_15_BEEP);
01097
01098 ShowEditorTerraformToolbar();
01099 return CBF_NONE;
01100 }
01101
01102
01103 static CallBackFunction ToolbarScenGenTown(Window *w)
01104 {
01105 w->HandleButtonClick(WID_TE_TOWN_GENERATE);
01106 SndPlayFx(SND_15_BEEP);
01107 ShowFoundTownWindow();
01108 return CBF_NONE;
01109 }
01110
01111 static CallBackFunction ToolbarScenGenIndustry(Window *w)
01112 {
01113 w->HandleButtonClick(WID_TE_INDUSTRY);
01114 SndPlayFx(SND_15_BEEP);
01115 ShowBuildIndustryWindow();
01116 return CBF_NONE;
01117 }
01118
01119 static CallBackFunction ToolbarScenBuildRoad(Window *w)
01120 {
01121 w->HandleButtonClick(WID_TE_ROADS);
01122 SndPlayFx(SND_15_BEEP);
01123 ShowBuildRoadScenToolbar();
01124 return CBF_NONE;
01125 }
01126
01127 static CallBackFunction ToolbarScenBuildDocks(Window *w)
01128 {
01129 w->HandleButtonClick(WID_TE_WATER);
01130 SndPlayFx(SND_15_BEEP);
01131 ShowBuildDocksScenToolbar();
01132 return CBF_NONE;
01133 }
01134
01135 static CallBackFunction ToolbarScenPlantTrees(Window *w)
01136 {
01137 w->HandleButtonClick(WID_TE_TREES);
01138 SndPlayFx(SND_15_BEEP);
01139 ShowBuildTreesToolbar();
01140 return CBF_NONE;
01141 }
01142
01143 static CallBackFunction ToolbarScenPlaceSign(Window *w)
01144 {
01145 w->HandleButtonClick(WID_TE_SIGNS);
01146 SndPlayFx(SND_15_BEEP);
01147 return SelectSignTool();
01148 }
01149
01150 static CallBackFunction ToolbarBtn_NULL(Window *w)
01151 {
01152 return CBF_NONE;
01153 }
01154
01155 typedef CallBackFunction MenuClickedProc(int index);
01156
01157 static MenuClickedProc * const _menu_clicked_procs[] = {
01158 NULL,
01159 NULL,
01160 MenuClickSettings,
01161 MenuClickSaveLoad,
01162 MenuClickMap,
01163 MenuClickTown,
01164 MenuClickSubsidies,
01165 MenuClickStations,
01166 MenuClickFinances,
01167 MenuClickCompany,
01168 MenuClickGraphs,
01169 MenuClickLeague,
01170 MenuClickIndustry,
01171 MenuClickShowTrains,
01172 MenuClickShowRoad,
01173 MenuClickShowShips,
01174 MenuClickShowAir,
01175 MenuClickMap,
01176 NULL,
01177 MenuClickBuildRail,
01178 MenuClickBuildRoad,
01179 MenuClickBuildWater,
01180 MenuClickBuildAir,
01181 MenuClickForest,
01182 MenuClickMusicWindow,
01183 MenuClickNewspaper,
01184 MenuClickHelp,
01185 };
01186
01187 int16 *_preferred_toolbar_size = NULL;
01188
01190 class NWidgetToolbarContainer : public NWidgetContainer {
01191 bool visible[WID_TN_END];
01192 protected:
01193 uint spacers;
01194
01195 public:
01196 NWidgetToolbarContainer() : NWidgetContainer(NWID_HORIZONTAL)
01197 {
01198 }
01199
01205 bool IsButton(WidgetType type) const
01206 {
01207 return type == WWT_IMGBTN || type == WWT_IMGBTN_2 || type == WWT_PUSHIMGBTN;
01208 }
01209
01210 void SetupSmallestSize(Window *w, bool init_array)
01211 {
01212 this->smallest_x = 0;
01213 this->smallest_y = 0;
01214 this->fill_x = 1;
01215 this->fill_y = 0;
01216 this->resize_x = 1;
01217 this->resize_y = 0;
01218 this->spacers = 0;
01219
01220 uint nbuttons = 0;
01221
01222 for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
01223 child_wid->SetupSmallestSize(w, init_array);
01224 this->smallest_y = max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom);
01225 if (this->IsButton(child_wid->type)) {
01226 nbuttons++;
01227 this->smallest_x = max(this->smallest_x, child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right);
01228 } else if (child_wid->type == NWID_SPACER) {
01229 this->spacers++;
01230 }
01231 }
01232
01233
01234 for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
01235 child_wid->current_y = this->smallest_y;
01236 if (!this->IsButton(child_wid->type)) {
01237 child_wid->current_x = child_wid->smallest_x;
01238 }
01239 }
01240 *_preferred_toolbar_size = nbuttons * this->smallest_x;
01241 }
01242
01243 void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl)
01244 {
01245 assert(given_width >= this->smallest_x && given_height >= this->smallest_y);
01246
01247 this->pos_x = x;
01248 this->pos_y = y;
01249 this->current_x = given_width;
01250 this->current_y = given_height;
01251
01252
01253 memset(this->visible, 0, sizeof(this->visible));
01254 uint arrangable_count, button_count, spacer_count;
01255 const byte *arrangement = GetButtonArrangement(given_width, arrangable_count, button_count, spacer_count);
01256 for (uint i = 0; i < arrangable_count; i++) {
01257 this->visible[arrangement[i]] = true;
01258 }
01259
01260
01261 NWidgetBase *widgets[WID_TN_END];
01262 for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
01263 if (child_wid->type == NWID_SPACER) continue;
01264 widgets[((NWidgetCore*)child_wid)->index] = child_wid;
01265 }
01266
01267
01268 uint position = 0;
01269 uint spacer_space = max(0, (int)given_width - (int)(button_count * this->smallest_x));
01270 uint button_space = given_width - spacer_space;
01271 uint spacer_i = 0;
01272 uint button_i = 0;
01273
01274
01275 const byte *cur_wid = rtl ? &arrangement[arrangable_count - 1] : arrangement;
01276 for (uint i = 0; i < arrangable_count; i++) {
01277 NWidgetBase *child_wid = widgets[*cur_wid];
01278
01279 if (spacer_space != 0) {
01280 NWidgetBase *possible_spacer = rtl ? child_wid->next : child_wid->prev;
01281 if (possible_spacer != NULL && possible_spacer->type == NWID_SPACER) {
01282 uint add = spacer_space / (spacer_count - spacer_i);
01283 position += add;
01284 spacer_space -= add;
01285 spacer_i++;
01286 }
01287 }
01288
01289
01290 if (this->IsButton(child_wid->type)) {
01291 child_wid->current_x = button_space / (button_count - button_i);
01292 button_space -= child_wid->current_x;
01293 button_i++;
01294 }
01295 child_wid->AssignSizePosition(sizing, x + position, y, child_wid->current_x, this->current_y, rtl);
01296 position += child_wid->current_x;
01297
01298 if (rtl) {
01299 cur_wid--;
01300 } else {
01301 cur_wid++;
01302 }
01303 }
01304 }
01305
01306 void Draw(const Window *w)
01307 {
01308
01309 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);
01310 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);
01311
01312 bool rtl = _current_text_dir == TD_RTL;
01313 for (NWidgetBase *child_wid = rtl ? this->tail : this->head; child_wid != NULL; child_wid = rtl ? child_wid->prev : child_wid->next) {
01314 if (child_wid->type == NWID_SPACER) continue;
01315 if (!this->visible[((NWidgetCore*)child_wid)->index]) continue;
01316
01317 child_wid->Draw(w);
01318 }
01319 }
01320
01321 NWidgetCore *GetWidgetFromPos(int x, int y)
01322 {
01323 if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return NULL;
01324
01325 for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
01326 if (child_wid->type == NWID_SPACER) continue;
01327 if (!this->visible[((NWidgetCore*)child_wid)->index]) continue;
01328
01329 NWidgetCore *nwid = child_wid->GetWidgetFromPos(x, y);
01330 if (nwid != NULL) return nwid;
01331 }
01332 return NULL;
01333 }
01334
01343 virtual const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const = 0;
01344 };
01345
01347 class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
01348 const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const
01349 {
01350 static const uint SMALLEST_ARRANGEMENT = 14;
01351 static const uint BIGGEST_ARRANGEMENT = 19;
01352 static const byte arrange14[] = {
01353 0, 1, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 27,
01354 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 24, 25, 26, 27,
01355 };
01356 static const byte arrange15[] = {
01357 0, 1, 4, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
01358 0, 2, 4, 3, 5, 6, 7, 8, 9, 10, 12, 24, 25, 26, 27,
01359 };
01360 static const byte arrange16[] = {
01361 0, 1, 2, 4, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
01362 0, 1, 3, 5, 6, 7, 8, 9, 10, 12, 24, 25, 26, 17, 18, 27,
01363 };
01364 static const byte arrange17[] = {
01365 0, 1, 2, 4, 6, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
01366 0, 1, 3, 4, 6, 5, 7, 8, 9, 10, 12, 24, 25, 26, 17, 18, 27,
01367 };
01368 static const byte arrange18[] = {
01369 0, 1, 2, 4, 5, 6, 7, 8, 9, 12, 19, 20, 21, 22, 23, 17, 18, 27,
01370 0, 1, 3, 4, 5, 6, 7, 10, 13, 14, 15, 16, 24, 25, 26, 17, 18, 27,
01371 };
01372 static const byte arrange19[] = {
01373 0, 1, 2, 4, 5, 6, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 17, 18, 27,
01374 0, 1, 3, 4, 7, 8, 9, 10, 12, 25, 19, 20, 21, 22, 23, 26, 17, 18, 27,
01375 };
01376 static const byte arrange_all[] = {
01377 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,
01378 };
01379
01380
01381 uint full_buttons = max(CeilDiv(width, this->smallest_x), SMALLEST_ARRANGEMENT);
01382 if (full_buttons > BIGGEST_ARRANGEMENT) {
01383 button_count = arrangable_count = lengthof(arrange_all);
01384 spacer_count = this->spacers;
01385 return arrange_all;
01386 }
01387
01388
01389 static const byte * const arrangements[] = { arrange14, arrange15, arrange16, arrange17, arrange18, arrange19 };
01390
01391 button_count = arrangable_count = full_buttons;
01392 spacer_count = this->spacers;
01393 return arrangements[full_buttons - SMALLEST_ARRANGEMENT] + ((_toolbar_mode == TB_LOWER) ? full_buttons : 0);
01394 }
01395 };
01396
01398 class NWidgetScenarioToolbarContainer : public NWidgetToolbarContainer {
01399 uint panel_widths[2];
01400
01401 void SetupSmallestSize(Window *w, bool init_array)
01402 {
01403 this->NWidgetToolbarContainer::SetupSmallestSize(w, init_array);
01404
01405
01406 uint i = 0;
01407 for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
01408 if (child_wid->type == NWID_SPACER || this->IsButton(child_wid->type)) continue;
01409
01410 assert(i < lengthof(this->panel_widths));
01411 this->panel_widths[i++] = child_wid->current_x;
01412 *_preferred_toolbar_size += child_wid->current_x;
01413 }
01414 }
01415
01416 const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const
01417 {
01418 static const byte arrange_all[] = {
01419 0, 1, 2, 3, 4, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 24, 26,
01420 };
01421 static const byte arrange_nopanel[] = {
01422 0, 1, 2, 3, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 24, 26,
01423 };
01424 static const byte arrange_switch[] = {
01425 18, 8, 11, 12, 13, 14, 15, 16, 17, 27,
01426 0, 1, 2, 3, 18, 9, 10, 24, 26, 27,
01427 };
01428
01429
01430 uint min_full_width = (lengthof(arrange_all) - lengthof(this->panel_widths)) * this->smallest_x + this->panel_widths[0] + this->panel_widths[1];
01431 if (width >= min_full_width) {
01432 width -= this->panel_widths[0] + this->panel_widths[1];
01433 arrangable_count = lengthof(arrange_all);
01434 button_count = arrangable_count - 2;
01435 spacer_count = this->spacers;
01436 return arrange_all;
01437 }
01438
01439
01440 uint min_small_width = (lengthof(arrange_switch) - lengthof(this->panel_widths)) * this->smallest_x / 2 + this->panel_widths[1];
01441 if (width > min_small_width) {
01442 width -= this->panel_widths[1];
01443 arrangable_count = lengthof(arrange_nopanel);
01444 button_count = arrangable_count - 1;
01445 spacer_count = this->spacers - 1;
01446 return arrange_nopanel;
01447 }
01448
01449
01450 width -= this->panel_widths[1];
01451 arrangable_count = lengthof(arrange_switch) / 2;
01452 button_count = arrangable_count - 1;
01453 spacer_count = 0;
01454 return arrange_switch + ((_toolbar_mode == TB_LOWER) ? arrangable_count : 0);
01455 }
01456 };
01457
01458
01459
01460 typedef CallBackFunction ToolbarButtonProc(Window *w);
01461
01462 static ToolbarButtonProc * const _toolbar_button_procs[] = {
01463 ToolbarPauseClick,
01464 ToolbarFastForwardClick,
01465 ToolbarOptionsClick,
01466 ToolbarSaveClick,
01467 ToolbarMapClick,
01468 ToolbarTownClick,
01469 ToolbarSubsidiesClick,
01470 ToolbarStationsClick,
01471 ToolbarFinancesClick,
01472 ToolbarCompaniesClick,
01473 ToolbarGraphsClick,
01474 ToolbarLeagueClick,
01475 ToolbarIndustryClick,
01476 ToolbarTrainClick,
01477 ToolbarRoadClick,
01478 ToolbarShipClick,
01479 ToolbarAirClick,
01480 ToolbarZoomInClick,
01481 ToolbarZoomOutClick,
01482 ToolbarBuildRailClick,
01483 ToolbarBuildRoadClick,
01484 ToolbarBuildWaterClick,
01485 ToolbarBuildAirClick,
01486 ToolbarForestClick,
01487 ToolbarMusicClick,
01488 ToolbarNewspaperClick,
01489 ToolbarHelpClick,
01490 ToolbarSwitchClick,
01491 };
01492
01493 enum MainToolbarHotkeys {
01494 MTHK_PAUSE,
01495 MTHK_FASTFORWARD,
01496 MTHK_SETTINGS,
01497 MTHK_SAVEGAME,
01498 MTHK_LOADGAME,
01499 MTHK_SMALLMAP,
01500 MTHK_TOWNDIRECTORY,
01501 MTHK_SUBSIDIES,
01502 MTHK_STATIONS,
01503 MTHK_FINANCES,
01504 MTHK_COMPANIES,
01505 MTHK_GRAPHS,
01506 MTHK_LEAGUE,
01507 MTHK_INDUSTRIES,
01508 MTHK_TRAIN_LIST,
01509 MTHK_ROADVEH_LIST,
01510 MTHK_SHIP_LIST,
01511 MTHK_AIRCRAFT_LIST,
01512 MTHK_ZOOM_IN,
01513 MTHK_ZOOM_OUT,
01514 MTHK_BUILD_RAIL,
01515 MTHK_BUILD_ROAD,
01516 MTHK_BUILD_DOCKS,
01517 MTHK_BUILD_AIRPORT,
01518 MTHK_BUILD_TREES,
01519 MTHK_MUSIC,
01520 MTHK_AI_DEBUG,
01521 MTHK_SMALL_SCREENSHOT,
01522 MTHK_ZOOMEDIN_SCREENSHOT,
01523 MTHK_DEFAULTZOOM_SCREENSHOT,
01524 MTHK_GIANT_SCREENSHOT,
01525 MTHK_CHEATS,
01526 MTHK_TERRAFORM,
01527 MTHK_EXTRA_VIEWPORT,
01528 MTHK_CLIENT_LIST,
01529 MTHK_SIGN_LIST,
01530 };
01531
01533 struct MainToolbarWindow : Window {
01534 CallBackFunction last_started_action;
01535
01536 MainToolbarWindow(const WindowDesc *desc) : Window()
01537 {
01538 this->InitNested(desc, 0);
01539
01540 this->last_started_action = CBF_NONE;
01541 CLRBITS(this->flags, WF_WHITE_BORDER);
01542 this->SetWidgetDisabledState(WID_TN_PAUSE, _networking && !_network_server);
01543 this->SetWidgetDisabledState(WID_TN_FAST_FORWARD, _networking);
01544 PositionMainToolbar(this);
01545 DoZoomInOutWindow(ZOOM_NONE, this);
01546 }
01547
01548 virtual void OnPaint()
01549 {
01550
01551
01552
01553 this->SetWidgetsDisabledState(_local_company == COMPANY_SPECTATOR, WID_TN_RAILS, WID_TN_ROADS, WID_TN_WATER, WID_TN_AIR, WID_TN_LANDSCAPE, WIDGET_LIST_END);
01554
01555 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);
01556
01557 this->SetWidgetDisabledState(WID_TN_RAILS, !CanBuildVehicleInfrastructure(VEH_TRAIN));
01558 this->SetWidgetDisabledState(WID_TN_AIR, !CanBuildVehicleInfrastructure(VEH_AIRCRAFT));
01559
01560 this->DrawWidgets();
01561 }
01562
01563 virtual void OnClick(Point pt, int widget, int click_count)
01564 {
01565 if (_game_mode != GM_MENU && !this->IsWidgetDisabled(widget)) _toolbar_button_procs[widget](this);
01566 }
01567
01568 virtual void OnDropdownSelect(int widget, int index)
01569 {
01570 CallBackFunction cbf = _menu_clicked_procs[widget](index);
01571 if (cbf != CBF_NONE) this->last_started_action = cbf;
01572 }
01573
01574 virtual EventState OnKeyPress(uint16 key, uint16 keycode)
01575 {
01576 switch (CheckHotkeyMatch(maintoolbar_hotkeys, keycode, this)) {
01577 case MTHK_PAUSE: ToolbarPauseClick(this); break;
01578 case MTHK_FASTFORWARD: ToolbarFastForwardClick(this); break;
01579 case MTHK_SETTINGS: ShowGameOptions(); break;
01580 case MTHK_SAVEGAME: MenuClickSaveLoad(); break;
01581 case MTHK_LOADGAME: ShowSaveLoadDialog(SLD_LOAD_GAME); break;
01582 case MTHK_SMALLMAP: ShowSmallMap(); break;
01583 case MTHK_TOWNDIRECTORY: ShowTownDirectory(); break;
01584 case MTHK_SUBSIDIES: ShowSubsidiesList(); break;
01585 case MTHK_STATIONS: ShowCompanyStations(_local_company); break;
01586 case MTHK_FINANCES: ShowCompanyFinances(_local_company); break;
01587 case MTHK_COMPANIES: ShowCompany(_local_company); break;
01588 case MTHK_GRAPHS: ShowOperatingProfitGraph(); break;
01589 case MTHK_LEAGUE: ShowCompanyLeagueTable(); break;
01590 case MTHK_INDUSTRIES: ShowBuildIndustryWindow(); break;
01591 case MTHK_TRAIN_LIST: ShowVehicleListWindow(_local_company, VEH_TRAIN); break;
01592 case MTHK_ROADVEH_LIST: ShowVehicleListWindow(_local_company, VEH_ROAD); break;
01593 case MTHK_SHIP_LIST: ShowVehicleListWindow(_local_company, VEH_SHIP); break;
01594 case MTHK_AIRCRAFT_LIST: ShowVehicleListWindow(_local_company, VEH_AIRCRAFT); break;
01595 case MTHK_ZOOM_IN: ToolbarZoomInClick(this); break;
01596 case MTHK_ZOOM_OUT: ToolbarZoomOutClick(this); break;
01597 case MTHK_BUILD_RAIL: if (CanBuildVehicleInfrastructure(VEH_TRAIN)) ShowBuildRailToolbar(_last_built_railtype); break;
01598 case MTHK_BUILD_ROAD: ShowBuildRoadToolbar(_last_built_roadtype); break;
01599 case MTHK_BUILD_DOCKS: ShowBuildDocksToolbar(); break;
01600 case MTHK_BUILD_AIRPORT: if (CanBuildVehicleInfrastructure(VEH_AIRCRAFT)) ShowBuildAirToolbar(); break;
01601 case MTHK_BUILD_TREES: ShowBuildTreesToolbar(); break;
01602 case MTHK_MUSIC: ShowMusicWindow(); break;
01603 case MTHK_AI_DEBUG: ShowAIDebugWindow(); break;
01604 case MTHK_SMALL_SCREENSHOT: MenuClickSmallScreenshot(); break;
01605 case MTHK_ZOOMEDIN_SCREENSHOT: MenuClickZoomedInScreenshot(); break;
01606 case MTHK_DEFAULTZOOM_SCREENSHOT: MenuClickDefaultZoomScreenshot(); break;
01607 case MTHK_GIANT_SCREENSHOT: MenuClickWorldScreenshot(); break;
01608 case MTHK_CHEATS: if (!_networking) ShowCheatWindow(); break;
01609 case MTHK_TERRAFORM: ShowTerraformToolbar(); break;
01610 case MTHK_EXTRA_VIEWPORT: ShowExtraViewPortWindowForTileUnderCursor(); break;
01611 #ifdef ENABLE_NETWORK
01612 case MTHK_CLIENT_LIST: if (_networking) ShowClientList(); break;
01613 #endif
01614 case MTHK_SIGN_LIST: ShowSignList(); break;
01615 default: return ES_NOT_HANDLED;
01616 }
01617 return ES_HANDLED;
01618 }
01619
01620 virtual void OnPlaceObject(Point pt, TileIndex tile)
01621 {
01622 switch (this->last_started_action) {
01623 case CBF_PLACE_SIGN:
01624 PlaceProc_Sign(tile);
01625 break;
01626
01627 case CBF_PLACE_LANDINFO:
01628 ShowLandInfo(tile);
01629 break;
01630
01631 default: NOT_REACHED();
01632 }
01633 }
01634
01635 virtual void OnTick()
01636 {
01637 if (this->IsWidgetLowered(WID_TN_PAUSE) != !!_pause_mode) {
01638 this->ToggleWidgetLoweredState(WID_TN_PAUSE);
01639 this->SetWidgetDirty(WID_TN_PAUSE);
01640 }
01641
01642 if (this->IsWidgetLowered(WID_TN_FAST_FORWARD) != !!_fast_forward) {
01643 this->ToggleWidgetLoweredState(WID_TN_FAST_FORWARD);
01644 this->SetWidgetDirty(WID_TN_FAST_FORWARD);
01645 }
01646 }
01647
01648 virtual void OnTimeout()
01649 {
01650
01651
01652 for (uint i = WID_TN_SETTINGS; i < WID_TN_SWITCH_BAR; i++) {
01653 if (this->IsWidgetLowered(i)) {
01654 this->RaiseWidget(i);
01655 this->SetWidgetDirty(i);
01656 }
01657 }
01658 }
01659
01665 virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
01666 {
01667 if (!gui_scope) return;
01668 if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, WID_TN_ZOOM_IN, WID_TN_ZOOM_OUT);
01669 }
01670
01671 static Hotkey<MainToolbarWindow> maintoolbar_hotkeys[];
01672 };
01673
01674 const uint16 _maintoolbar_pause_keys[] = {WKC_F1, WKC_PAUSE, 0};
01675 const uint16 _maintoolbar_zoomin_keys[] = {WKC_NUM_PLUS, WKC_EQUALS, WKC_SHIFT | WKC_EQUALS, WKC_SHIFT | WKC_F5, 0};
01676 const uint16 _maintoolbar_zoomout_keys[] = {WKC_NUM_MINUS, WKC_MINUS, WKC_SHIFT | WKC_MINUS, WKC_SHIFT | WKC_F6, 0};
01677 const uint16 _maintoolbar_smallmap_keys[] = {WKC_F4, 'M', 0};
01678
01679 Hotkey<MainToolbarWindow> MainToolbarWindow::maintoolbar_hotkeys[] = {
01680 Hotkey<MainToolbarWindow>(_maintoolbar_pause_keys, "pause", MTHK_PAUSE),
01681 Hotkey<MainToolbarWindow>((uint16)0, "fastforward", MTHK_FASTFORWARD),
01682 Hotkey<MainToolbarWindow>(WKC_F2, "settings", MTHK_SETTINGS),
01683 Hotkey<MainToolbarWindow>(WKC_F3, "saveload", MTHK_SAVEGAME),
01684 Hotkey<MainToolbarWindow>((uint16)0, "load_game", MTHK_LOADGAME),
01685 Hotkey<MainToolbarWindow>(_maintoolbar_smallmap_keys, "smallmap", MTHK_SMALLMAP),
01686 Hotkey<MainToolbarWindow>(WKC_F5, "town_list", MTHK_TOWNDIRECTORY),
01687 Hotkey<MainToolbarWindow>(WKC_F6, "subsidies", MTHK_SUBSIDIES),
01688 Hotkey<MainToolbarWindow>(WKC_F7, "station_list", MTHK_STATIONS),
01689 Hotkey<MainToolbarWindow>(WKC_F8, "finances", MTHK_FINANCES),
01690 Hotkey<MainToolbarWindow>(WKC_F9, "companies", MTHK_COMPANIES),
01691 Hotkey<MainToolbarWindow>(WKC_F10, "graphs", MTHK_GRAPHS),
01692 Hotkey<MainToolbarWindow>(WKC_F11, "league", MTHK_LEAGUE),
01693 Hotkey<MainToolbarWindow>(WKC_F12, "industry_list", MTHK_INDUSTRIES),
01694 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F1, "train_list", MTHK_TRAIN_LIST),
01695 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F2, "roadveh_list", MTHK_ROADVEH_LIST),
01696 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F3, "ship_list", MTHK_SHIP_LIST),
01697 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F4, "aircraft_list", MTHK_AIRCRAFT_LIST),
01698 Hotkey<MainToolbarWindow>(_maintoolbar_zoomin_keys, "zoomin", MTHK_ZOOM_IN),
01699 Hotkey<MainToolbarWindow>(_maintoolbar_zoomout_keys, "zoomout", MTHK_ZOOM_OUT),
01700 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F7, "build_rail", MTHK_BUILD_RAIL),
01701 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F8, "build_road", MTHK_BUILD_ROAD),
01702 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F9, "build_docks", MTHK_BUILD_DOCKS),
01703 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F10, "build_airport", MTHK_BUILD_AIRPORT),
01704 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F11, "build_trees", MTHK_BUILD_TREES),
01705 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F12, "music", MTHK_MUSIC),
01706 Hotkey<MainToolbarWindow>((uint16)0, "ai_debug", MTHK_AI_DEBUG),
01707 Hotkey<MainToolbarWindow>(WKC_CTRL | 'S', "small_screenshot", MTHK_SMALL_SCREENSHOT),
01708 Hotkey<MainToolbarWindow>(WKC_CTRL | 'P', "zoomedin_screenshot", MTHK_ZOOMEDIN_SCREENSHOT),
01709 Hotkey<MainToolbarWindow>(WKC_CTRL | 'D', "defaultzoom_screenshot", MTHK_DEFAULTZOOM_SCREENSHOT),
01710 Hotkey<MainToolbarWindow>((uint16)0, "giant_screenshot", MTHK_GIANT_SCREENSHOT),
01711 Hotkey<MainToolbarWindow>(WKC_CTRL | WKC_ALT | 'C', "cheats", MTHK_CHEATS),
01712 Hotkey<MainToolbarWindow>('L', "terraform", MTHK_TERRAFORM),
01713 Hotkey<MainToolbarWindow>('V', "extra_viewport", MTHK_EXTRA_VIEWPORT),
01714 #ifdef ENABLE_NETWORK
01715 Hotkey<MainToolbarWindow>((uint16)0, "client_list", MTHK_CLIENT_LIST),
01716 #endif
01717 Hotkey<MainToolbarWindow>((uint16)0, "sign_list", MTHK_SIGN_LIST),
01718 HOTKEY_LIST_END(MainToolbarWindow)
01719 };
01720 Hotkey<MainToolbarWindow> *_maintoolbar_hotkeys = MainToolbarWindow::maintoolbar_hotkeys;
01721
01722 static NWidgetBase *MakeMainToolbar(int *biggest_index)
01723 {
01725 static const SpriteID toolbar_button_sprites[] = {
01726 SPR_IMG_PAUSE,
01727 SPR_IMG_FASTFORWARD,
01728 SPR_IMG_SETTINGS,
01729 SPR_IMG_SAVE,
01730 SPR_IMG_SMALLMAP,
01731 SPR_IMG_TOWN,
01732 SPR_IMG_SUBSIDIES,
01733 SPR_IMG_COMPANY_LIST,
01734 SPR_IMG_COMPANY_FINANCE,
01735 SPR_IMG_COMPANY_GENERAL,
01736 SPR_IMG_GRAPHS,
01737 SPR_IMG_COMPANY_LEAGUE,
01738 SPR_IMG_INDUSTRY,
01739 SPR_IMG_TRAINLIST,
01740 SPR_IMG_TRUCKLIST,
01741 SPR_IMG_SHIPLIST,
01742 SPR_IMG_AIRPLANESLIST,
01743 SPR_IMG_ZOOMIN,
01744 SPR_IMG_ZOOMOUT,
01745 SPR_IMG_BUILDRAIL,
01746 SPR_IMG_BUILDROAD,
01747 SPR_IMG_BUILDWATER,
01748 SPR_IMG_BUILDAIR,
01749 SPR_IMG_LANDSCAPING,
01750 SPR_IMG_MUSIC,
01751 SPR_IMG_MESSAGES,
01752 SPR_IMG_QUERY,
01753 SPR_IMG_SWITCH_TOOLBAR,
01754 };
01755
01756 NWidgetMainToolbarContainer *hor = new NWidgetMainToolbarContainer();
01757 for (uint i = 0; i < WID_TN_END; i++) {
01758 switch (i) {
01759 case 4: case 8: case 13: case 17: case 19: case 24: hor->Add(new NWidgetSpacer(0, 0)); break;
01760 }
01761 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));
01762 }
01763
01764 *biggest_index = max<int>(*biggest_index, WID_TN_SWITCH_BAR);
01765 return hor;
01766 }
01767
01768 static const NWidgetPart _nested_toolbar_normal_widgets[] = {
01769 NWidgetFunction(MakeMainToolbar),
01770 };
01771
01772 static WindowDesc _toolb_normal_desc(
01773 WDP_MANUAL, 640, 22,
01774 WC_MAIN_TOOLBAR, WC_NONE,
01775 WDF_NO_FOCUS,
01776 _nested_toolbar_normal_widgets, lengthof(_nested_toolbar_normal_widgets)
01777 );
01778
01779
01780
01781
01782 static ToolbarButtonProc * const _scen_toolbar_button_procs[] = {
01783 ToolbarPauseClick,
01784 ToolbarFastForwardClick,
01785 ToolbarOptionsClick,
01786 ToolbarScenSaveOrLoad,
01787 ToolbarBtn_NULL,
01788 ToolbarScenDatePanel,
01789 ToolbarScenDateBackward,
01790 ToolbarScenDateForward,
01791 ToolbarScenMapTownDir,
01792 ToolbarZoomInClick,
01793 ToolbarZoomOutClick,
01794 ToolbarScenGenLand,
01795 ToolbarScenGenTown,
01796 ToolbarScenGenIndustry,
01797 ToolbarScenBuildRoad,
01798 ToolbarScenBuildDocks,
01799 ToolbarScenPlantTrees,
01800 ToolbarScenPlaceSign,
01801 ToolbarBtn_NULL,
01802 NULL,
01803 NULL,
01804 NULL,
01805 NULL,
01806 NULL,
01807 ToolbarMusicClick,
01808 NULL,
01809 ToolbarHelpClick,
01810 ToolbarSwitchClick,
01811 };
01812
01813 enum MainToolbarEditorHotkeys {
01814 MTEHK_PAUSE,
01815 MTEHK_FASTFORWARD,
01816 MTEHK_SETTINGS,
01817 MTEHK_SAVEGAME,
01818 MTEHK_GENLAND,
01819 MTEHK_GENTOWN,
01820 MTEHK_GENINDUSTRY,
01821 MTEHK_BUILD_ROAD,
01822 MTEHK_BUILD_DOCKS,
01823 MTEHK_BUILD_TREES,
01824 MTEHK_SIGN,
01825 MTEHK_MUSIC,
01826 MTEHK_LANDINFO,
01827 MTEHK_SMALL_SCREENSHOT,
01828 MTEHK_ZOOMEDIN_SCREENSHOT,
01829 MTEHK_DEFAULTZOOM_SCREENSHOT,
01830 MTEHK_GIANT_SCREENSHOT,
01831 MTEHK_ZOOM_IN,
01832 MTEHK_ZOOM_OUT,
01833 MTEHK_TERRAFORM,
01834 MTEHK_SMALLMAP,
01835 MTEHK_EXTRA_VIEWPORT,
01836 };
01837
01838 struct ScenarioEditorToolbarWindow : Window {
01839 CallBackFunction last_started_action;
01840
01841 ScenarioEditorToolbarWindow(const WindowDesc *desc) : Window()
01842 {
01843 this->InitNested(desc, 0);
01844
01845 this->last_started_action = CBF_NONE;
01846 CLRBITS(this->flags, WF_WHITE_BORDER);
01847 PositionMainToolbar(this);
01848 DoZoomInOutWindow(ZOOM_NONE, this);
01849 }
01850
01851 virtual void OnPaint()
01852 {
01853 this->SetWidgetDisabledState(WID_TE_DATE_BACKWARD, _settings_game.game_creation.starting_year <= MIN_YEAR);
01854 this->SetWidgetDisabledState(WID_TE_DATE_FORWARD, _settings_game.game_creation.starting_year >= MAX_YEAR);
01855
01856 this->DrawWidgets();
01857 }
01858
01859 virtual void DrawWidget(const Rect &r, int widget) const
01860 {
01861 switch (widget) {
01862 case WID_TE_DATE:
01863 SetDParam(0, ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
01864 DrawString(r.left, r.right, (this->height - FONT_HEIGHT_NORMAL) / 2, STR_WHITE_DATE_LONG, TC_FROMSTRING, SA_HOR_CENTER);
01865 break;
01866
01867 case WID_TE_SPACER: {
01868 int height = r.bottom - r.top;
01869 if (height > 2 * FONT_HEIGHT_NORMAL) {
01870 DrawString(r.left, r.right, (height + 1) / 2 - FONT_HEIGHT_NORMAL, STR_SCENEDIT_TOOLBAR_OPENTTD, TC_FROMSTRING, SA_HOR_CENTER);
01871 DrawString(r.left, r.right, (height + 1) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_HOR_CENTER);
01872 } else {
01873 DrawString(r.left, r.right, (height - FONT_HEIGHT_NORMAL) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_HOR_CENTER);
01874 }
01875 break;
01876 }
01877 }
01878 }
01879
01880 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
01881 {
01882 switch (widget) {
01883 case WID_TE_SPACER:
01884 size->width = max(GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_OPENTTD).width, GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR).width) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
01885 break;
01886
01887 case WID_TE_DATE:
01888 SetDParam(0, ConvertYMDToDate(MAX_YEAR, 0, 1));
01889 *size = GetStringBoundingBox(STR_WHITE_DATE_LONG);
01890 size->height = max(size->height, GetSpriteSize(SPR_IMG_SAVE).height + WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM);
01891 break;
01892 }
01893 }
01894
01895 virtual void OnClick(Point pt, int widget, int click_count)
01896 {
01897 if (_game_mode == GM_MENU) return;
01898 CallBackFunction cbf = _scen_toolbar_button_procs[widget](this);
01899 if (cbf != CBF_NONE) this->last_started_action = cbf;
01900 }
01901
01902 virtual void OnDropdownSelect(int widget, int index)
01903 {
01904
01905
01906 if (widget == WID_TE_SMALL_MAP) widget = WID_TN_SMALL_MAP;
01907 CallBackFunction cbf = _menu_clicked_procs[widget](index);
01908 if (cbf != CBF_NONE) this->last_started_action = cbf;
01909 SndPlayFx(SND_15_BEEP);
01910 }
01911
01912 virtual EventState OnKeyPress(uint16 key, uint16 keycode)
01913 {
01914 CallBackFunction cbf = CBF_NONE;
01915 switch (CheckHotkeyMatch(scenedit_maintoolbar_hotkeys, keycode, this)) {
01916 case MTEHK_PAUSE: ToolbarPauseClick(this); break;
01917 case MTEHK_FASTFORWARD: ToolbarFastForwardClick(this); break;
01918 case MTEHK_SETTINGS: ShowGameOptions(); break;
01919 case MTEHK_SAVEGAME: MenuClickSaveLoad(); break;
01920 case MTEHK_GENLAND: ToolbarScenGenLand(this); break;
01921 case MTEHK_GENTOWN: ToolbarScenGenTown(this); break;
01922 case MTEHK_GENINDUSTRY: ToolbarScenGenIndustry(this); break;
01923 case MTEHK_BUILD_ROAD: ToolbarScenBuildRoad(this); break;
01924 case MTEHK_BUILD_DOCKS: ToolbarScenBuildDocks(this); break;
01925 case MTEHK_BUILD_TREES: ToolbarScenPlantTrees(this); break;
01926 case MTEHK_SIGN: cbf = ToolbarScenPlaceSign(this); break;
01927 case MTEHK_MUSIC: ShowMusicWindow(); break;
01928 case MTEHK_LANDINFO: cbf = PlaceLandBlockInfo(); break;
01929 case MTEHK_SMALL_SCREENSHOT: MenuClickSmallScreenshot(); break;
01930 case MTEHK_ZOOMEDIN_SCREENSHOT: MenuClickZoomedInScreenshot(); break;
01931 case MTEHK_DEFAULTZOOM_SCREENSHOT: MenuClickDefaultZoomScreenshot(); break;
01932 case MTEHK_GIANT_SCREENSHOT: MenuClickWorldScreenshot(); break;
01933 case MTEHK_ZOOM_IN: ToolbarZoomInClick(this); break;
01934 case MTEHK_ZOOM_OUT: ToolbarZoomOutClick(this); break;
01935 case MTEHK_TERRAFORM: ShowEditorTerraformToolbar(); break;
01936 case MTEHK_SMALLMAP: ShowSmallMap(); break;
01937 case MTEHK_EXTRA_VIEWPORT: ShowExtraViewPortWindowForTileUnderCursor(); break;
01938 default: return ES_NOT_HANDLED;
01939 }
01940 if (cbf != CBF_NONE) this->last_started_action = cbf;
01941 return ES_HANDLED;
01942 }
01943
01944 virtual void OnPlaceObject(Point pt, TileIndex tile)
01945 {
01946 switch (this->last_started_action) {
01947 case CBF_PLACE_SIGN:
01948 PlaceProc_Sign(tile);
01949 break;
01950
01951 case CBF_PLACE_LANDINFO:
01952 ShowLandInfo(tile);
01953 break;
01954
01955 default: NOT_REACHED();
01956 }
01957 }
01958
01959 virtual void OnTimeout()
01960 {
01961 this->SetWidgetsLoweredState(false, WID_TE_DATE_BACKWARD, WID_TE_DATE_FORWARD, WIDGET_LIST_END);
01962 this->SetWidgetDirty(WID_TE_DATE_BACKWARD);
01963 this->SetWidgetDirty(WID_TE_DATE_FORWARD);
01964 }
01965
01966 virtual void OnTick()
01967 {
01968 if (this->IsWidgetLowered(WID_TE_PAUSE) != !!_pause_mode) {
01969 this->ToggleWidgetLoweredState(WID_TE_PAUSE);
01970 this->SetDirty();
01971 }
01972
01973 if (this->IsWidgetLowered(WID_TE_FAST_FORWARD) != !!_fast_forward) {
01974 this->ToggleWidgetLoweredState(WID_TE_FAST_FORWARD);
01975 this->SetDirty();
01976 }
01977 }
01978
01984 virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
01985 {
01986 if (!gui_scope) return;
01987 if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, WID_TE_ZOOM_IN, WID_TE_ZOOM_OUT);
01988 }
01989
01990 virtual void OnQueryTextFinished(char *str)
01991 {
01992
01993 if (str == NULL) return;
01994
01995 int32 value;
01996 if (!StrEmpty(str)) {
01997 value = atoi(str);
01998 } else {
01999
02000 value = DEF_START_YEAR;
02001 }
02002 _settings_game.game_creation.starting_year = Clamp(value, MIN_YEAR, MAX_YEAR);
02003 SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0);
02004
02005 this->SetDirty();
02006 }
02007
02008 static Hotkey<ScenarioEditorToolbarWindow> scenedit_maintoolbar_hotkeys[];
02009 };
02010
02011 Hotkey<ScenarioEditorToolbarWindow> ScenarioEditorToolbarWindow::scenedit_maintoolbar_hotkeys[] = {
02012 Hotkey<ScenarioEditorToolbarWindow>(_maintoolbar_pause_keys, "pause", MTEHK_PAUSE),
02013 Hotkey<ScenarioEditorToolbarWindow>((uint16)0, "fastforward", MTEHK_FASTFORWARD),
02014 Hotkey<ScenarioEditorToolbarWindow>(WKC_F2, "settings", MTEHK_SETTINGS),
02015 Hotkey<ScenarioEditorToolbarWindow>(WKC_F3, "saveload", MTEHK_SAVEGAME),
02016 Hotkey<ScenarioEditorToolbarWindow>(WKC_F4, "gen_land", MTEHK_GENLAND),
02017 Hotkey<ScenarioEditorToolbarWindow>(WKC_F5, "gen_town", MTEHK_GENTOWN),
02018 Hotkey<ScenarioEditorToolbarWindow>(WKC_F6, "gen_industry", MTEHK_GENINDUSTRY),
02019 Hotkey<ScenarioEditorToolbarWindow>(WKC_F7, "build_road", MTEHK_BUILD_ROAD),
02020 Hotkey<ScenarioEditorToolbarWindow>(WKC_F8, "build_docks", MTEHK_BUILD_DOCKS),
02021 Hotkey<ScenarioEditorToolbarWindow>(WKC_F9, "build_trees", MTEHK_BUILD_TREES),
02022 Hotkey<ScenarioEditorToolbarWindow>(WKC_F10, "build_sign", MTEHK_SIGN),
02023 Hotkey<ScenarioEditorToolbarWindow>(WKC_F11, "music", MTEHK_MUSIC),
02024 Hotkey<ScenarioEditorToolbarWindow>(WKC_F12, "land_info", MTEHK_LANDINFO),
02025 Hotkey<ScenarioEditorToolbarWindow>(WKC_CTRL | 'S', "small_screenshot", MTEHK_SMALL_SCREENSHOT),
02026 Hotkey<ScenarioEditorToolbarWindow>(WKC_CTRL | 'P', "zoomedin_screenshot", MTEHK_ZOOMEDIN_SCREENSHOT),
02027 Hotkey<ScenarioEditorToolbarWindow>(WKC_CTRL | 'D', "defaultzoom_screenshot", MTEHK_DEFAULTZOOM_SCREENSHOT),
02028 Hotkey<ScenarioEditorToolbarWindow>((uint16)0, "giant_screenshot", MTEHK_GIANT_SCREENSHOT),
02029 Hotkey<ScenarioEditorToolbarWindow>(_maintoolbar_zoomin_keys, "zoomin", MTEHK_ZOOM_IN),
02030 Hotkey<ScenarioEditorToolbarWindow>(_maintoolbar_zoomout_keys, "zoomout", MTEHK_ZOOM_OUT),
02031 Hotkey<ScenarioEditorToolbarWindow>('L', "terraform", MTEHK_TERRAFORM),
02032 Hotkey<ScenarioEditorToolbarWindow>('M', "smallmap", MTEHK_SMALLMAP),
02033 Hotkey<ScenarioEditorToolbarWindow>('V', "extra_viewport", MTEHK_EXTRA_VIEWPORT),
02034 HOTKEY_LIST_END(ScenarioEditorToolbarWindow)
02035 };
02036 Hotkey<ScenarioEditorToolbarWindow> *_scenedit_maintoolbar_hotkeys = ScenarioEditorToolbarWindow::scenedit_maintoolbar_hotkeys;
02037
02038 static const NWidgetPart _nested_toolb_scen_inner_widgets[] = {
02039 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_PAUSE), SetDataTip(SPR_IMG_PAUSE, STR_TOOLBAR_TOOLTIP_PAUSE_GAME),
02040 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_FAST_FORWARD), SetDataTip(SPR_IMG_FASTFORWARD, STR_TOOLBAR_TOOLTIP_FORWARD),
02041 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_SETTINGS), SetDataTip(SPR_IMG_SETTINGS, STR_TOOLBAR_TOOLTIP_OPTIONS),
02042 NWidget(WWT_IMGBTN_2, COLOUR_GREY, WID_TE_SAVE), SetDataTip(SPR_IMG_SAVE, STR_SCENEDIT_TOOLBAR_TOOLTIP_SAVE_SCENARIO_LOAD_SCENARIO),
02043 NWidget(NWID_SPACER),
02044 NWidget(WWT_PANEL, COLOUR_GREY, WID_TE_SPACER), EndContainer(),
02045 NWidget(NWID_SPACER),
02046 NWidget(WWT_PANEL, COLOUR_GREY, WID_TE_DATE_PANEL),
02047 NWidget(NWID_HORIZONTAL), SetPIP(3, 2, 3),
02048 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_DATE_BACKWARD), SetDataTip(SPR_ARROW_DOWN, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD),
02049 NWidget(WWT_EMPTY, COLOUR_GREY, WID_TE_DATE), SetDataTip(STR_NULL, STR_SCENEDIT_TOOLBAR_TOOLTIP_SET_DATE),
02050 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_DATE_FORWARD), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD),
02051 EndContainer(),
02052 EndContainer(),
02053 NWidget(NWID_SPACER),
02054 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_SMALL_MAP), SetDataTip(SPR_IMG_SMALLMAP, STR_SCENEDIT_TOOLBAR_TOOLTIP_DISPLAY_MAP_TOWN_DIRECTORY),
02055 NWidget(NWID_SPACER),
02056 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_ZOOM_IN), SetDataTip(SPR_IMG_ZOOMIN, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN),
02057 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_ZOOM_OUT), SetDataTip(SPR_IMG_ZOOMOUT, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT),
02058 NWidget(NWID_SPACER),
02059 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_LAND_GENERATE), SetDataTip(SPR_IMG_LANDSCAPING, STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION),
02060 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_TOWN_GENERATE), SetDataTip(SPR_IMG_TOWN, STR_SCENEDIT_TOOLBAR_TOWN_GENERATION),
02061 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_INDUSTRY), SetDataTip(SPR_IMG_INDUSTRY, STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION),
02062 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_ROADS), SetDataTip(SPR_IMG_BUILDROAD, STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION),
02063 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_WATER), SetDataTip(SPR_IMG_BUILDWATER, STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS),
02064 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_TREES), SetDataTip(SPR_IMG_PLANTTREES, STR_SCENEDIT_TOOLBAR_PLANT_TREES),
02065 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_SIGNS), SetDataTip(SPR_IMG_SIGN, STR_SCENEDIT_TOOLBAR_PLACE_SIGN),
02066 NWidget(NWID_SPACER),
02067 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_MUSIC_SOUND), SetDataTip(SPR_IMG_MUSIC, STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW),
02068 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_HELP), SetDataTip(SPR_IMG_QUERY, STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION),
02069 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_SWITCH_BAR), SetDataTip(SPR_IMG_SWITCH_TOOLBAR, STR_TOOLBAR_TOOLTIP_SWITCH_TOOLBAR),
02070 };
02071
02072 static NWidgetBase *MakeScenarioToolbar(int *biggest_index)
02073 {
02074 return MakeNWidgets(_nested_toolb_scen_inner_widgets, lengthof(_nested_toolb_scen_inner_widgets), biggest_index, new NWidgetScenarioToolbarContainer());
02075 }
02076
02077 static const NWidgetPart _nested_toolb_scen_widgets[] = {
02078 NWidgetFunction(MakeScenarioToolbar),
02079 };
02080
02081 static WindowDesc _toolb_scen_desc(
02082 WDP_MANUAL, 640, 22,
02083 WC_MAIN_TOOLBAR, WC_NONE,
02084 WDF_UNCLICK_BUTTONS | WDF_NO_FOCUS,
02085 _nested_toolb_scen_widgets, lengthof(_nested_toolb_scen_widgets)
02086 );
02087
02089 void AllocateToolbar()
02090 {
02091
02092 _last_built_roadtype = ROADTYPE_ROAD;
02093
02094 if (_game_mode == GM_EDITOR) {
02095 _preferred_toolbar_size = &_toolb_scen_desc.default_width;
02096 new ScenarioEditorToolbarWindow(&_toolb_scen_desc);
02097 } else {
02098 _preferred_toolbar_size = &_toolb_normal_desc.default_width;
02099 new MainToolbarWindow(&_toolb_normal_desc);
02100 }
02101 }