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,
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 ? 11 : 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
01001 static CallBackFunction MenuClickHelp(int index)
01002 {
01003 switch (index) {
01004 case 0: return PlaceLandBlockInfo();
01005 case 2: IConsoleSwitch(); break;
01006 case 3: ShowAIDebugWindow(); break;
01007 case 4: MenuClickSmallScreenshot(); break;
01008 case 5: MenuClickZoomedInScreenshot(); break;
01009 case 6: MenuClickDefaultZoomScreenshot(); break;
01010 case 7: MenuClickWorldScreenshot(); break;
01011 case 8: ShowAboutWindow(); break;
01012 case 9: ShowSpriteAlignerWindow(); break;
01013 case 10: ToggleBoundingBoxes(); break;
01014 }
01015 return CBF_NONE;
01016 }
01017
01018
01019
01020 static CallBackFunction ToolbarSwitchClick(Window *w)
01021 {
01022 if (_toolbar_mode != TB_LOWER) {
01023 _toolbar_mode = TB_LOWER;
01024 } else {
01025 _toolbar_mode = TB_UPPER;
01026 }
01027
01028 w->ReInit();
01029 w->SetWidgetLoweredState(WID_TN_SWITCH_BAR, _toolbar_mode == TB_LOWER);
01030 SndPlayFx(SND_15_BEEP);
01031 return CBF_NONE;
01032 }
01033
01034
01035
01039 static CallBackFunction ToolbarScenDatePanel(Window *w)
01040 {
01041 SetDParam(0, _settings_game.game_creation.starting_year);
01042 ShowQueryString(STR_JUST_INT, STR_MAPGEN_START_DATE_QUERY_CAPT, 8, w, CS_NUMERAL, QSF_ENABLE_DEFAULT);
01043 _left_button_clicked = false;
01044 return CBF_NONE;
01045 }
01046
01047 static CallBackFunction ToolbarScenDateBackward(Window *w)
01048 {
01049
01050 if (!(w->flags & WF_TIMEOUT) || w->timeout_timer <= 1) {
01051 w->HandleButtonClick(WID_TE_DATE_BACKWARD);
01052 w->SetDirty();
01053
01054 _settings_game.game_creation.starting_year = Clamp(_settings_game.game_creation.starting_year - 1, MIN_YEAR, MAX_YEAR);
01055 SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0);
01056 }
01057 _left_button_clicked = false;
01058 return CBF_NONE;
01059 }
01060
01061 static CallBackFunction ToolbarScenDateForward(Window *w)
01062 {
01063
01064 if (!(w->flags & WF_TIMEOUT) || w->timeout_timer <= 1) {
01065 w->HandleButtonClick(WID_TE_DATE_FORWARD);
01066 w->SetDirty();
01067
01068 _settings_game.game_creation.starting_year = Clamp(_settings_game.game_creation.starting_year + 1, MIN_YEAR, MAX_YEAR);
01069 SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0);
01070 }
01071 _left_button_clicked = false;
01072 return CBF_NONE;
01073 }
01074
01075 static CallBackFunction ToolbarScenGenLand(Window *w)
01076 {
01077 w->HandleButtonClick(WID_TE_LAND_GENERATE);
01078 SndPlayFx(SND_15_BEEP);
01079
01080 ShowEditorTerraformToolbar();
01081 return CBF_NONE;
01082 }
01083
01084
01085 static CallBackFunction ToolbarScenGenTown(Window *w)
01086 {
01087 w->HandleButtonClick(WID_TE_TOWN_GENERATE);
01088 SndPlayFx(SND_15_BEEP);
01089 ShowFoundTownWindow();
01090 return CBF_NONE;
01091 }
01092
01093 static CallBackFunction ToolbarScenGenIndustry(Window *w)
01094 {
01095 w->HandleButtonClick(WID_TE_INDUSTRY);
01096 SndPlayFx(SND_15_BEEP);
01097 ShowBuildIndustryWindow();
01098 return CBF_NONE;
01099 }
01100
01101 static CallBackFunction ToolbarScenBuildRoad(Window *w)
01102 {
01103 w->HandleButtonClick(WID_TE_ROADS);
01104 SndPlayFx(SND_15_BEEP);
01105 ShowBuildRoadScenToolbar();
01106 return CBF_NONE;
01107 }
01108
01109 static CallBackFunction ToolbarScenBuildDocks(Window *w)
01110 {
01111 w->HandleButtonClick(WID_TE_WATER);
01112 SndPlayFx(SND_15_BEEP);
01113 ShowBuildDocksScenToolbar();
01114 return CBF_NONE;
01115 }
01116
01117 static CallBackFunction ToolbarScenPlantTrees(Window *w)
01118 {
01119 w->HandleButtonClick(WID_TE_TREES);
01120 SndPlayFx(SND_15_BEEP);
01121 ShowBuildTreesToolbar();
01122 return CBF_NONE;
01123 }
01124
01125 static CallBackFunction ToolbarScenPlaceSign(Window *w)
01126 {
01127 w->HandleButtonClick(WID_TE_SIGNS);
01128 SndPlayFx(SND_15_BEEP);
01129 return SelectSignTool();
01130 }
01131
01132 static CallBackFunction ToolbarBtn_NULL(Window *w)
01133 {
01134 return CBF_NONE;
01135 }
01136
01137 typedef CallBackFunction MenuClickedProc(int index);
01138
01139 static MenuClickedProc * const _menu_clicked_procs[] = {
01140 NULL,
01141 NULL,
01142 MenuClickSettings,
01143 MenuClickSaveLoad,
01144 MenuClickMap,
01145 MenuClickTown,
01146 MenuClickSubsidies,
01147 MenuClickStations,
01148 MenuClickFinances,
01149 MenuClickCompany,
01150 MenuClickGraphs,
01151 MenuClickLeague,
01152 MenuClickIndustry,
01153 MenuClickShowTrains,
01154 MenuClickShowRoad,
01155 MenuClickShowShips,
01156 MenuClickShowAir,
01157 MenuClickMap,
01158 NULL,
01159 MenuClickBuildRail,
01160 MenuClickBuildRoad,
01161 MenuClickBuildWater,
01162 MenuClickBuildAir,
01163 MenuClickForest,
01164 MenuClickMusicWindow,
01165 MenuClickNewspaper,
01166 MenuClickHelp,
01167 };
01168
01169 int16 *_preferred_toolbar_size = NULL;
01170
01172 class NWidgetToolbarContainer : public NWidgetContainer {
01173 bool visible[WID_TN_END];
01174 protected:
01175 uint spacers;
01176
01177 public:
01178 NWidgetToolbarContainer() : NWidgetContainer(NWID_HORIZONTAL)
01179 {
01180 }
01181
01187 bool IsButton(WidgetType type) const
01188 {
01189 return type == WWT_IMGBTN || type == WWT_IMGBTN_2 || type == WWT_PUSHIMGBTN;
01190 }
01191
01192 void SetupSmallestSize(Window *w, bool init_array)
01193 {
01194 this->smallest_x = 0;
01195 this->smallest_y = 0;
01196 this->fill_x = 1;
01197 this->fill_y = 0;
01198 this->resize_x = 1;
01199 this->resize_y = 0;
01200 this->spacers = 0;
01201
01202 uint nbuttons = 0;
01203
01204 for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
01205 child_wid->SetupSmallestSize(w, init_array);
01206 this->smallest_y = max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom);
01207 if (this->IsButton(child_wid->type)) {
01208 nbuttons++;
01209 this->smallest_x = max(this->smallest_x, child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right);
01210 } else if (child_wid->type == NWID_SPACER) {
01211 this->spacers++;
01212 }
01213 }
01214
01215
01216 for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
01217 child_wid->current_y = this->smallest_y;
01218 if (!this->IsButton(child_wid->type)) {
01219 child_wid->current_x = child_wid->smallest_x;
01220 }
01221 }
01222 *_preferred_toolbar_size = nbuttons * this->smallest_x;
01223 }
01224
01225 void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl)
01226 {
01227 assert(given_width >= this->smallest_x && given_height >= this->smallest_y);
01228
01229 this->pos_x = x;
01230 this->pos_y = y;
01231 this->current_x = given_width;
01232 this->current_y = given_height;
01233
01234
01235 memset(this->visible, 0, sizeof(this->visible));
01236 uint arrangable_count, button_count, spacer_count;
01237 const byte *arrangement = GetButtonArrangement(given_width, arrangable_count, button_count, spacer_count);
01238 for (uint i = 0; i < arrangable_count; i++) {
01239 this->visible[arrangement[i]] = true;
01240 }
01241
01242
01243 NWidgetBase *widgets[WID_TN_END];
01244 for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
01245 if (child_wid->type == NWID_SPACER) continue;
01246 widgets[((NWidgetCore*)child_wid)->index] = child_wid;
01247 }
01248
01249
01250 uint position = 0;
01251 uint spacer_space = max(0, (int)given_width - (int)(button_count * this->smallest_x));
01252 uint button_space = given_width - spacer_space;
01253 uint spacer_i = 0;
01254 uint button_i = 0;
01255
01256
01257 const byte *cur_wid = rtl ? &arrangement[arrangable_count - 1] : arrangement;
01258 for (uint i = 0; i < arrangable_count; i++) {
01259 NWidgetBase *child_wid = widgets[*cur_wid];
01260
01261 if (spacer_space != 0) {
01262 NWidgetBase *possible_spacer = rtl ? child_wid->next : child_wid->prev;
01263 if (possible_spacer != NULL && possible_spacer->type == NWID_SPACER) {
01264 uint add = spacer_space / (spacer_count - spacer_i);
01265 position += add;
01266 spacer_space -= add;
01267 spacer_i++;
01268 }
01269 }
01270
01271
01272 if (this->IsButton(child_wid->type)) {
01273 child_wid->current_x = button_space / (button_count - button_i);
01274 button_space -= child_wid->current_x;
01275 button_i++;
01276 }
01277 child_wid->AssignSizePosition(sizing, x + position, y, child_wid->current_x, this->current_y, rtl);
01278 position += child_wid->current_x;
01279
01280 if (rtl) {
01281 cur_wid--;
01282 } else {
01283 cur_wid++;
01284 }
01285 }
01286 }
01287
01288 void Draw(const Window *w)
01289 {
01290
01291 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);
01292 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);
01293
01294 bool rtl = _current_text_dir == TD_RTL;
01295 for (NWidgetBase *child_wid = rtl ? this->tail : this->head; child_wid != NULL; child_wid = rtl ? child_wid->prev : child_wid->next) {
01296 if (child_wid->type == NWID_SPACER) continue;
01297 if (!this->visible[((NWidgetCore*)child_wid)->index]) continue;
01298
01299 child_wid->Draw(w);
01300 }
01301 }
01302
01303 NWidgetCore *GetWidgetFromPos(int x, int y)
01304 {
01305 if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return NULL;
01306
01307 for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
01308 if (child_wid->type == NWID_SPACER) continue;
01309 if (!this->visible[((NWidgetCore*)child_wid)->index]) continue;
01310
01311 NWidgetCore *nwid = child_wid->GetWidgetFromPos(x, y);
01312 if (nwid != NULL) return nwid;
01313 }
01314 return NULL;
01315 }
01316
01325 virtual const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const = 0;
01326 };
01327
01329 class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
01330 const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const
01331 {
01332 static const uint SMALLEST_ARRANGEMENT = 14;
01333 static const uint BIGGEST_ARRANGEMENT = 19;
01334 static const byte arrange14[] = {
01335 0, 1, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 27,
01336 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 24, 25, 26, 27,
01337 };
01338 static const byte arrange15[] = {
01339 0, 1, 4, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
01340 0, 2, 4, 3, 5, 6, 7, 8, 9, 10, 12, 24, 25, 26, 27,
01341 };
01342 static const byte arrange16[] = {
01343 0, 1, 2, 4, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
01344 0, 1, 3, 5, 6, 7, 8, 9, 10, 12, 24, 25, 26, 17, 18, 27,
01345 };
01346 static const byte arrange17[] = {
01347 0, 1, 2, 4, 6, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
01348 0, 1, 3, 4, 6, 5, 7, 8, 9, 10, 12, 24, 25, 26, 17, 18, 27,
01349 };
01350 static const byte arrange18[] = {
01351 0, 1, 2, 4, 5, 6, 7, 8, 9, 12, 19, 20, 21, 22, 23, 17, 18, 27,
01352 0, 1, 3, 4, 5, 6, 7, 10, 13, 14, 15, 16, 24, 25, 26, 17, 18, 27,
01353 };
01354 static const byte arrange19[] = {
01355 0, 1, 2, 4, 5, 6, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 17, 18, 27,
01356 0, 1, 3, 4, 7, 8, 9, 10, 12, 25, 19, 20, 21, 22, 23, 26, 17, 18, 27,
01357 };
01358 static const byte arrange_all[] = {
01359 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,
01360 };
01361
01362
01363 uint full_buttons = max(CeilDiv(width, this->smallest_x), SMALLEST_ARRANGEMENT);
01364 if (full_buttons > BIGGEST_ARRANGEMENT) {
01365 button_count = arrangable_count = lengthof(arrange_all);
01366 spacer_count = this->spacers;
01367 return arrange_all;
01368 }
01369
01370
01371 static const byte * const arrangements[] = { arrange14, arrange15, arrange16, arrange17, arrange18, arrange19 };
01372
01373 button_count = arrangable_count = full_buttons;
01374 spacer_count = this->spacers;
01375 return arrangements[full_buttons - SMALLEST_ARRANGEMENT] + ((_toolbar_mode == TB_LOWER) ? full_buttons : 0);
01376 }
01377 };
01378
01380 class NWidgetScenarioToolbarContainer : public NWidgetToolbarContainer {
01381 uint panel_widths[2];
01382
01383 void SetupSmallestSize(Window *w, bool init_array)
01384 {
01385 this->NWidgetToolbarContainer::SetupSmallestSize(w, init_array);
01386
01387
01388 uint i = 0;
01389 for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
01390 if (child_wid->type == NWID_SPACER || this->IsButton(child_wid->type)) continue;
01391
01392 assert(i < lengthof(this->panel_widths));
01393 this->panel_widths[i++] = child_wid->current_x;
01394 *_preferred_toolbar_size += child_wid->current_x;
01395 }
01396 }
01397
01398 const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const
01399 {
01400 static const byte arrange_all[] = {
01401 0, 1, 2, 3, 4, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 24, 26,
01402 };
01403 static const byte arrange_nopanel[] = {
01404 0, 1, 2, 3, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 24, 26,
01405 };
01406 static const byte arrange_switch[] = {
01407 18, 8, 11, 12, 13, 14, 15, 16, 17, 27,
01408 0, 1, 2, 3, 18, 9, 10, 24, 26, 27,
01409 };
01410
01411
01412 uint min_full_width = (lengthof(arrange_all) - lengthof(this->panel_widths)) * this->smallest_x + this->panel_widths[0] + this->panel_widths[1];
01413 if (width >= min_full_width) {
01414 width -= this->panel_widths[0] + this->panel_widths[1];
01415 arrangable_count = lengthof(arrange_all);
01416 button_count = arrangable_count - 2;
01417 spacer_count = this->spacers;
01418 return arrange_all;
01419 }
01420
01421
01422 uint min_small_width = (lengthof(arrange_switch) - lengthof(this->panel_widths)) * this->smallest_x / 2 + this->panel_widths[1];
01423 if (width > min_small_width) {
01424 width -= this->panel_widths[1];
01425 arrangable_count = lengthof(arrange_nopanel);
01426 button_count = arrangable_count - 1;
01427 spacer_count = this->spacers - 1;
01428 return arrange_nopanel;
01429 }
01430
01431
01432 width -= this->panel_widths[1];
01433 arrangable_count = lengthof(arrange_switch) / 2;
01434 button_count = arrangable_count - 1;
01435 spacer_count = 0;
01436 return arrange_switch + ((_toolbar_mode == TB_LOWER) ? arrangable_count : 0);
01437 }
01438 };
01439
01440
01441
01442 typedef CallBackFunction ToolbarButtonProc(Window *w);
01443
01444 static ToolbarButtonProc * const _toolbar_button_procs[] = {
01445 ToolbarPauseClick,
01446 ToolbarFastForwardClick,
01447 ToolbarOptionsClick,
01448 ToolbarSaveClick,
01449 ToolbarMapClick,
01450 ToolbarTownClick,
01451 ToolbarSubsidiesClick,
01452 ToolbarStationsClick,
01453 ToolbarFinancesClick,
01454 ToolbarCompaniesClick,
01455 ToolbarGraphsClick,
01456 ToolbarLeagueClick,
01457 ToolbarIndustryClick,
01458 ToolbarTrainClick,
01459 ToolbarRoadClick,
01460 ToolbarShipClick,
01461 ToolbarAirClick,
01462 ToolbarZoomInClick,
01463 ToolbarZoomOutClick,
01464 ToolbarBuildRailClick,
01465 ToolbarBuildRoadClick,
01466 ToolbarBuildWaterClick,
01467 ToolbarBuildAirClick,
01468 ToolbarForestClick,
01469 ToolbarMusicClick,
01470 ToolbarNewspaperClick,
01471 ToolbarHelpClick,
01472 ToolbarSwitchClick,
01473 };
01474
01475 enum MainToolbarHotkeys {
01476 MTHK_PAUSE,
01477 MTHK_FASTFORWARD,
01478 MTHK_SETTINGS,
01479 MTHK_SAVEGAME,
01480 MTHK_LOADGAME,
01481 MTHK_SMALLMAP,
01482 MTHK_TOWNDIRECTORY,
01483 MTHK_SUBSIDIES,
01484 MTHK_STATIONS,
01485 MTHK_FINANCES,
01486 MTHK_COMPANIES,
01487 MTHK_GRAPHS,
01488 MTHK_LEAGUE,
01489 MTHK_INDUSTRIES,
01490 MTHK_TRAIN_LIST,
01491 MTHK_ROADVEH_LIST,
01492 MTHK_SHIP_LIST,
01493 MTHK_AIRCRAFT_LIST,
01494 MTHK_ZOOM_IN,
01495 MTHK_ZOOM_OUT,
01496 MTHK_BUILD_RAIL,
01497 MTHK_BUILD_ROAD,
01498 MTHK_BUILD_DOCKS,
01499 MTHK_BUILD_AIRPORT,
01500 MTHK_BUILD_TREES,
01501 MTHK_MUSIC,
01502 MTHK_AI_DEBUG,
01503 MTHK_SMALL_SCREENSHOT,
01504 MTHK_ZOOMEDIN_SCREENSHOT,
01505 MTHK_DEFAULTZOOM_SCREENSHOT,
01506 MTHK_GIANT_SCREENSHOT,
01507 MTHK_CHEATS,
01508 MTHK_TERRAFORM,
01509 MTHK_EXTRA_VIEWPORT,
01510 MTHK_CLIENT_LIST,
01511 MTHK_SIGN_LIST,
01512 };
01513
01515 struct MainToolbarWindow : Window {
01516 CallBackFunction last_started_action;
01517
01518 MainToolbarWindow(const WindowDesc *desc) : Window()
01519 {
01520 this->InitNested(desc, 0);
01521
01522 this->last_started_action = CBF_NONE;
01523 CLRBITS(this->flags, WF_WHITE_BORDER);
01524 this->SetWidgetDisabledState(WID_TN_PAUSE, _networking && !_network_server);
01525 this->SetWidgetDisabledState(WID_TN_FAST_FORWARD, _networking);
01526 PositionMainToolbar(this);
01527 DoZoomInOutWindow(ZOOM_NONE, this);
01528 }
01529
01530 virtual void OnPaint()
01531 {
01532
01533
01534
01535 this->SetWidgetsDisabledState(_local_company == COMPANY_SPECTATOR, WID_TN_RAILS, WID_TN_ROADS, WID_TN_WATER, WID_TN_AIR, WID_TN_LANDSCAPE, WIDGET_LIST_END);
01536
01537 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);
01538
01539 this->SetWidgetDisabledState(WID_TN_RAILS, !CanBuildVehicleInfrastructure(VEH_TRAIN));
01540 this->SetWidgetDisabledState(WID_TN_AIR, !CanBuildVehicleInfrastructure(VEH_AIRCRAFT));
01541
01542 this->DrawWidgets();
01543 }
01544
01545 virtual void OnClick(Point pt, int widget, int click_count)
01546 {
01547 if (_game_mode != GM_MENU && !this->IsWidgetDisabled(widget)) _toolbar_button_procs[widget](this);
01548 }
01549
01550 virtual void OnDropdownSelect(int widget, int index)
01551 {
01552 CallBackFunction cbf = _menu_clicked_procs[widget](index);
01553 if (cbf != CBF_NONE) this->last_started_action = cbf;
01554 }
01555
01556 virtual EventState OnKeyPress(uint16 key, uint16 keycode)
01557 {
01558 switch (CheckHotkeyMatch(maintoolbar_hotkeys, keycode, this)) {
01559 case MTHK_PAUSE: ToolbarPauseClick(this); break;
01560 case MTHK_FASTFORWARD: ToolbarFastForwardClick(this); break;
01561 case MTHK_SETTINGS: ShowGameOptions(); break;
01562 case MTHK_SAVEGAME: MenuClickSaveLoad(); break;
01563 case MTHK_LOADGAME: ShowSaveLoadDialog(SLD_LOAD_GAME); break;
01564 case MTHK_SMALLMAP: ShowSmallMap(); break;
01565 case MTHK_TOWNDIRECTORY: ShowTownDirectory(); break;
01566 case MTHK_SUBSIDIES: ShowSubsidiesList(); break;
01567 case MTHK_STATIONS: ShowCompanyStations(_local_company); break;
01568 case MTHK_FINANCES: ShowCompanyFinances(_local_company); break;
01569 case MTHK_COMPANIES: ShowCompany(_local_company); break;
01570 case MTHK_GRAPHS: ShowOperatingProfitGraph(); break;
01571 case MTHK_LEAGUE: ShowCompanyLeagueTable(); break;
01572 case MTHK_INDUSTRIES: ShowBuildIndustryWindow(); break;
01573 case MTHK_TRAIN_LIST: ShowVehicleListWindow(_local_company, VEH_TRAIN); break;
01574 case MTHK_ROADVEH_LIST: ShowVehicleListWindow(_local_company, VEH_ROAD); break;
01575 case MTHK_SHIP_LIST: ShowVehicleListWindow(_local_company, VEH_SHIP); break;
01576 case MTHK_AIRCRAFT_LIST: ShowVehicleListWindow(_local_company, VEH_AIRCRAFT); break;
01577 case MTHK_ZOOM_IN: ToolbarZoomInClick(this); break;
01578 case MTHK_ZOOM_OUT: ToolbarZoomOutClick(this); break;
01579 case MTHK_BUILD_RAIL: if (CanBuildVehicleInfrastructure(VEH_TRAIN)) ShowBuildRailToolbar(_last_built_railtype); break;
01580 case MTHK_BUILD_ROAD: ShowBuildRoadToolbar(_last_built_roadtype); break;
01581 case MTHK_BUILD_DOCKS: ShowBuildDocksToolbar(); break;
01582 case MTHK_BUILD_AIRPORT: if (CanBuildVehicleInfrastructure(VEH_AIRCRAFT)) ShowBuildAirToolbar(); break;
01583 case MTHK_BUILD_TREES: ShowBuildTreesToolbar(); break;
01584 case MTHK_MUSIC: ShowMusicWindow(); break;
01585 case MTHK_AI_DEBUG: ShowAIDebugWindow(); break;
01586 case MTHK_SMALL_SCREENSHOT: MenuClickSmallScreenshot(); break;
01587 case MTHK_ZOOMEDIN_SCREENSHOT: MenuClickZoomedInScreenshot(); break;
01588 case MTHK_DEFAULTZOOM_SCREENSHOT: MenuClickDefaultZoomScreenshot(); break;
01589 case MTHK_GIANT_SCREENSHOT: MenuClickWorldScreenshot(); break;
01590 case MTHK_CHEATS: if (!_networking) ShowCheatWindow(); break;
01591 case MTHK_TERRAFORM: ShowTerraformToolbar(); break;
01592 case MTHK_EXTRA_VIEWPORT: ShowExtraViewPortWindowForTileUnderCursor(); break;
01593 #ifdef ENABLE_NETWORK
01594 case MTHK_CLIENT_LIST: if (_networking) ShowClientList(); break;
01595 #endif
01596 case MTHK_SIGN_LIST: ShowSignList(); break;
01597 default: return ES_NOT_HANDLED;
01598 }
01599 return ES_HANDLED;
01600 }
01601
01602 virtual void OnPlaceObject(Point pt, TileIndex tile)
01603 {
01604 switch (this->last_started_action) {
01605 case CBF_PLACE_SIGN:
01606 PlaceProc_Sign(tile);
01607 break;
01608
01609 case CBF_PLACE_LANDINFO:
01610 ShowLandInfo(tile);
01611 break;
01612
01613 default: NOT_REACHED();
01614 }
01615 }
01616
01617 virtual void OnTick()
01618 {
01619 if (this->IsWidgetLowered(WID_TN_PAUSE) != !!_pause_mode) {
01620 this->ToggleWidgetLoweredState(WID_TN_PAUSE);
01621 this->SetWidgetDirty(WID_TN_PAUSE);
01622 }
01623
01624 if (this->IsWidgetLowered(WID_TN_FAST_FORWARD) != !!_fast_forward) {
01625 this->ToggleWidgetLoweredState(WID_TN_FAST_FORWARD);
01626 this->SetWidgetDirty(WID_TN_FAST_FORWARD);
01627 }
01628 }
01629
01630 virtual void OnTimeout()
01631 {
01632
01633
01634 for (uint i = WID_TN_SETTINGS; i < WID_TN_SWITCH_BAR; i++) {
01635 if (this->IsWidgetLowered(i)) {
01636 this->RaiseWidget(i);
01637 this->SetWidgetDirty(i);
01638 }
01639 }
01640 }
01641
01647 virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
01648 {
01649 if (!gui_scope) return;
01650 if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, WID_TN_ZOOM_IN, WID_TN_ZOOM_OUT);
01651 }
01652
01653 static Hotkey<MainToolbarWindow> maintoolbar_hotkeys[];
01654 };
01655
01656 const uint16 _maintoolbar_pause_keys[] = {WKC_F1, WKC_PAUSE, 0};
01657 const uint16 _maintoolbar_zoomin_keys[] = {WKC_NUM_PLUS, WKC_EQUALS, WKC_SHIFT | WKC_EQUALS, WKC_SHIFT | WKC_F5, 0};
01658 const uint16 _maintoolbar_zoomout_keys[] = {WKC_NUM_MINUS, WKC_MINUS, WKC_SHIFT | WKC_MINUS, WKC_SHIFT | WKC_F6, 0};
01659 const uint16 _maintoolbar_smallmap_keys[] = {WKC_F4, 'M', 0};
01660
01661 Hotkey<MainToolbarWindow> MainToolbarWindow::maintoolbar_hotkeys[] = {
01662 Hotkey<MainToolbarWindow>(_maintoolbar_pause_keys, "pause", MTHK_PAUSE),
01663 Hotkey<MainToolbarWindow>((uint16)0, "fastforward", MTHK_FASTFORWARD),
01664 Hotkey<MainToolbarWindow>(WKC_F2, "settings", MTHK_SETTINGS),
01665 Hotkey<MainToolbarWindow>(WKC_F3, "saveload", MTHK_SAVEGAME),
01666 Hotkey<MainToolbarWindow>((uint16)0, "load_game", MTHK_LOADGAME),
01667 Hotkey<MainToolbarWindow>(_maintoolbar_smallmap_keys, "smallmap", MTHK_SMALLMAP),
01668 Hotkey<MainToolbarWindow>(WKC_F5, "town_list", MTHK_TOWNDIRECTORY),
01669 Hotkey<MainToolbarWindow>(WKC_F6, "subsidies", MTHK_SUBSIDIES),
01670 Hotkey<MainToolbarWindow>(WKC_F7, "station_list", MTHK_STATIONS),
01671 Hotkey<MainToolbarWindow>(WKC_F8, "finances", MTHK_FINANCES),
01672 Hotkey<MainToolbarWindow>(WKC_F9, "companies", MTHK_COMPANIES),
01673 Hotkey<MainToolbarWindow>(WKC_F10, "graphs", MTHK_GRAPHS),
01674 Hotkey<MainToolbarWindow>(WKC_F11, "league", MTHK_LEAGUE),
01675 Hotkey<MainToolbarWindow>(WKC_F12, "industry_list", MTHK_INDUSTRIES),
01676 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F1, "train_list", MTHK_TRAIN_LIST),
01677 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F2, "roadveh_list", MTHK_ROADVEH_LIST),
01678 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F3, "ship_list", MTHK_SHIP_LIST),
01679 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F4, "aircraft_list", MTHK_AIRCRAFT_LIST),
01680 Hotkey<MainToolbarWindow>(_maintoolbar_zoomin_keys, "zoomin", MTHK_ZOOM_IN),
01681 Hotkey<MainToolbarWindow>(_maintoolbar_zoomout_keys, "zoomout", MTHK_ZOOM_OUT),
01682 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F7, "build_rail", MTHK_BUILD_RAIL),
01683 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F8, "build_road", MTHK_BUILD_ROAD),
01684 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F9, "build_docks", MTHK_BUILD_DOCKS),
01685 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F10, "build_airport", MTHK_BUILD_AIRPORT),
01686 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F11, "build_trees", MTHK_BUILD_TREES),
01687 Hotkey<MainToolbarWindow>(WKC_SHIFT | WKC_F12, "music", MTHK_MUSIC),
01688 Hotkey<MainToolbarWindow>((uint16)0, "ai_debug", MTHK_AI_DEBUG),
01689 Hotkey<MainToolbarWindow>(WKC_CTRL | 'S', "small_screenshot", MTHK_SMALL_SCREENSHOT),
01690 Hotkey<MainToolbarWindow>(WKC_CTRL | 'P', "zoomedin_screenshot", MTHK_ZOOMEDIN_SCREENSHOT),
01691 Hotkey<MainToolbarWindow>(WKC_CTRL | 'D', "defaultzoom_screenshot", MTHK_DEFAULTZOOM_SCREENSHOT),
01692 Hotkey<MainToolbarWindow>((uint16)0, "giant_screenshot", MTHK_GIANT_SCREENSHOT),
01693 Hotkey<MainToolbarWindow>(WKC_CTRL | WKC_ALT | 'C', "cheats", MTHK_CHEATS),
01694 Hotkey<MainToolbarWindow>('L', "terraform", MTHK_TERRAFORM),
01695 Hotkey<MainToolbarWindow>('V', "extra_viewport", MTHK_EXTRA_VIEWPORT),
01696 #ifdef ENABLE_NETWORK
01697 Hotkey<MainToolbarWindow>((uint16)0, "client_list", MTHK_CLIENT_LIST),
01698 #endif
01699 Hotkey<MainToolbarWindow>((uint16)0, "sign_list", MTHK_SIGN_LIST),
01700 HOTKEY_LIST_END(MainToolbarWindow)
01701 };
01702 Hotkey<MainToolbarWindow> *_maintoolbar_hotkeys = MainToolbarWindow::maintoolbar_hotkeys;
01703
01704 static NWidgetBase *MakeMainToolbar(int *biggest_index)
01705 {
01707 static const SpriteID toolbar_button_sprites[] = {
01708 SPR_IMG_PAUSE,
01709 SPR_IMG_FASTFORWARD,
01710 SPR_IMG_SETTINGS,
01711 SPR_IMG_SAVE,
01712 SPR_IMG_SMALLMAP,
01713 SPR_IMG_TOWN,
01714 SPR_IMG_SUBSIDIES,
01715 SPR_IMG_COMPANY_LIST,
01716 SPR_IMG_COMPANY_FINANCE,
01717 SPR_IMG_COMPANY_GENERAL,
01718 SPR_IMG_GRAPHS,
01719 SPR_IMG_COMPANY_LEAGUE,
01720 SPR_IMG_INDUSTRY,
01721 SPR_IMG_TRAINLIST,
01722 SPR_IMG_TRUCKLIST,
01723 SPR_IMG_SHIPLIST,
01724 SPR_IMG_AIRPLANESLIST,
01725 SPR_IMG_ZOOMIN,
01726 SPR_IMG_ZOOMOUT,
01727 SPR_IMG_BUILDRAIL,
01728 SPR_IMG_BUILDROAD,
01729 SPR_IMG_BUILDWATER,
01730 SPR_IMG_BUILDAIR,
01731 SPR_IMG_LANDSCAPING,
01732 SPR_IMG_MUSIC,
01733 SPR_IMG_MESSAGES,
01734 SPR_IMG_QUERY,
01735 SPR_IMG_SWITCH_TOOLBAR,
01736 };
01737
01738 NWidgetMainToolbarContainer *hor = new NWidgetMainToolbarContainer();
01739 for (uint i = 0; i < WID_TN_END; i++) {
01740 switch (i) {
01741 case 4: case 8: case 13: case 17: case 19: case 24: hor->Add(new NWidgetSpacer(0, 0)); break;
01742 }
01743 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));
01744 }
01745
01746 *biggest_index = max<int>(*biggest_index, WID_TN_SWITCH_BAR);
01747 return hor;
01748 }
01749
01750 static const NWidgetPart _nested_toolbar_normal_widgets[] = {
01751 NWidgetFunction(MakeMainToolbar),
01752 };
01753
01754 static WindowDesc _toolb_normal_desc(
01755 WDP_MANUAL, 640, 22,
01756 WC_MAIN_TOOLBAR, WC_NONE,
01757 WDF_NO_FOCUS,
01758 _nested_toolbar_normal_widgets, lengthof(_nested_toolbar_normal_widgets)
01759 );
01760
01761
01762
01763
01764 static ToolbarButtonProc * const _scen_toolbar_button_procs[] = {
01765 ToolbarPauseClick,
01766 ToolbarFastForwardClick,
01767 ToolbarOptionsClick,
01768 ToolbarScenSaveOrLoad,
01769 ToolbarBtn_NULL,
01770 ToolbarScenDatePanel,
01771 ToolbarScenDateBackward,
01772 ToolbarScenDateForward,
01773 ToolbarScenMapTownDir,
01774 ToolbarZoomInClick,
01775 ToolbarZoomOutClick,
01776 ToolbarScenGenLand,
01777 ToolbarScenGenTown,
01778 ToolbarScenGenIndustry,
01779 ToolbarScenBuildRoad,
01780 ToolbarScenBuildDocks,
01781 ToolbarScenPlantTrees,
01782 ToolbarScenPlaceSign,
01783 ToolbarBtn_NULL,
01784 NULL,
01785 NULL,
01786 NULL,
01787 NULL,
01788 NULL,
01789 ToolbarMusicClick,
01790 NULL,
01791 ToolbarHelpClick,
01792 ToolbarSwitchClick,
01793 };
01794
01795 enum MainToolbarEditorHotkeys {
01796 MTEHK_PAUSE,
01797 MTEHK_FASTFORWARD,
01798 MTEHK_SETTINGS,
01799 MTEHK_SAVEGAME,
01800 MTEHK_GENLAND,
01801 MTEHK_GENTOWN,
01802 MTEHK_GENINDUSTRY,
01803 MTEHK_BUILD_ROAD,
01804 MTEHK_BUILD_DOCKS,
01805 MTEHK_BUILD_TREES,
01806 MTEHK_SIGN,
01807 MTEHK_MUSIC,
01808 MTEHK_LANDINFO,
01809 MTEHK_SMALL_SCREENSHOT,
01810 MTEHK_ZOOMEDIN_SCREENSHOT,
01811 MTEHK_DEFAULTZOOM_SCREENSHOT,
01812 MTEHK_GIANT_SCREENSHOT,
01813 MTEHK_ZOOM_IN,
01814 MTEHK_ZOOM_OUT,
01815 MTEHK_TERRAFORM,
01816 MTEHK_SMALLMAP,
01817 MTEHK_EXTRA_VIEWPORT,
01818 };
01819
01820 struct ScenarioEditorToolbarWindow : Window {
01821 CallBackFunction last_started_action;
01822
01823 ScenarioEditorToolbarWindow(const WindowDesc *desc) : Window()
01824 {
01825 this->InitNested(desc, 0);
01826
01827 this->last_started_action = CBF_NONE;
01828 CLRBITS(this->flags, WF_WHITE_BORDER);
01829 PositionMainToolbar(this);
01830 DoZoomInOutWindow(ZOOM_NONE, this);
01831 }
01832
01833 virtual void OnPaint()
01834 {
01835 this->SetWidgetDisabledState(WID_TE_DATE_BACKWARD, _settings_game.game_creation.starting_year <= MIN_YEAR);
01836 this->SetWidgetDisabledState(WID_TE_DATE_FORWARD, _settings_game.game_creation.starting_year >= MAX_YEAR);
01837
01838 this->DrawWidgets();
01839 }
01840
01841 virtual void DrawWidget(const Rect &r, int widget) const
01842 {
01843 switch (widget) {
01844 case WID_TE_DATE:
01845 SetDParam(0, ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
01846 DrawString(r.left, r.right, (this->height - FONT_HEIGHT_NORMAL) / 2, STR_WHITE_DATE_LONG, TC_FROMSTRING, SA_HOR_CENTER);
01847 break;
01848
01849 case WID_TE_SPACER: {
01850 int height = r.bottom - r.top;
01851 if (height > 2 * FONT_HEIGHT_NORMAL) {
01852 DrawString(r.left, r.right, (height + 1) / 2 - FONT_HEIGHT_NORMAL, STR_SCENEDIT_TOOLBAR_OPENTTD, TC_FROMSTRING, SA_HOR_CENTER);
01853 DrawString(r.left, r.right, (height + 1) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_HOR_CENTER);
01854 } else {
01855 DrawString(r.left, r.right, (height - FONT_HEIGHT_NORMAL) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_HOR_CENTER);
01856 }
01857 break;
01858 }
01859 }
01860 }
01861
01862 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
01863 {
01864 switch (widget) {
01865 case WID_TE_SPACER:
01866 size->width = max(GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_OPENTTD).width, GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR).width) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
01867 break;
01868
01869 case WID_TE_DATE:
01870 SetDParam(0, ConvertYMDToDate(MAX_YEAR, 0, 1));
01871 *size = GetStringBoundingBox(STR_WHITE_DATE_LONG);
01872 size->height = max(size->height, GetSpriteSize(SPR_IMG_SAVE).height + WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM);
01873 break;
01874 }
01875 }
01876
01877 virtual void OnClick(Point pt, int widget, int click_count)
01878 {
01879 if (_game_mode == GM_MENU) return;
01880 CallBackFunction cbf = _scen_toolbar_button_procs[widget](this);
01881 if (cbf != CBF_NONE) this->last_started_action = cbf;
01882 }
01883
01884 virtual void OnDropdownSelect(int widget, int index)
01885 {
01886
01887
01888 if (widget == WID_TE_SMALL_MAP) widget = WID_TN_SMALL_MAP;
01889 CallBackFunction cbf = _menu_clicked_procs[widget](index);
01890 if (cbf != CBF_NONE) this->last_started_action = cbf;
01891 SndPlayFx(SND_15_BEEP);
01892 }
01893
01894 virtual EventState OnKeyPress(uint16 key, uint16 keycode)
01895 {
01896 CallBackFunction cbf = CBF_NONE;
01897 switch (CheckHotkeyMatch(scenedit_maintoolbar_hotkeys, keycode, this)) {
01898 case MTEHK_PAUSE: ToolbarPauseClick(this); break;
01899 case MTEHK_FASTFORWARD: ToolbarFastForwardClick(this); break;
01900 case MTEHK_SETTINGS: ShowGameOptions(); break;
01901 case MTEHK_SAVEGAME: MenuClickSaveLoad(); break;
01902 case MTEHK_GENLAND: ToolbarScenGenLand(this); break;
01903 case MTEHK_GENTOWN: ToolbarScenGenTown(this); break;
01904 case MTEHK_GENINDUSTRY: ToolbarScenGenIndustry(this); break;
01905 case MTEHK_BUILD_ROAD: ToolbarScenBuildRoad(this); break;
01906 case MTEHK_BUILD_DOCKS: ToolbarScenBuildDocks(this); break;
01907 case MTEHK_BUILD_TREES: ToolbarScenPlantTrees(this); break;
01908 case MTEHK_SIGN: cbf = ToolbarScenPlaceSign(this); break;
01909 case MTEHK_MUSIC: ShowMusicWindow(); break;
01910 case MTEHK_LANDINFO: cbf = PlaceLandBlockInfo(); break;
01911 case MTEHK_SMALL_SCREENSHOT: MenuClickSmallScreenshot(); break;
01912 case MTEHK_ZOOMEDIN_SCREENSHOT: MenuClickZoomedInScreenshot(); break;
01913 case MTEHK_DEFAULTZOOM_SCREENSHOT: MenuClickDefaultZoomScreenshot(); break;
01914 case MTEHK_GIANT_SCREENSHOT: MenuClickWorldScreenshot(); break;
01915 case MTEHK_ZOOM_IN: ToolbarZoomInClick(this); break;
01916 case MTEHK_ZOOM_OUT: ToolbarZoomOutClick(this); break;
01917 case MTEHK_TERRAFORM: ShowEditorTerraformToolbar(); break;
01918 case MTEHK_SMALLMAP: ShowSmallMap(); break;
01919 case MTEHK_EXTRA_VIEWPORT: ShowExtraViewPortWindowForTileUnderCursor(); break;
01920 default: return ES_NOT_HANDLED;
01921 }
01922 if (cbf != CBF_NONE) this->last_started_action = cbf;
01923 return ES_HANDLED;
01924 }
01925
01926 virtual void OnPlaceObject(Point pt, TileIndex tile)
01927 {
01928 switch (this->last_started_action) {
01929 case CBF_PLACE_SIGN:
01930 PlaceProc_Sign(tile);
01931 break;
01932
01933 case CBF_PLACE_LANDINFO:
01934 ShowLandInfo(tile);
01935 break;
01936
01937 default: NOT_REACHED();
01938 }
01939 }
01940
01941 virtual void OnTimeout()
01942 {
01943 this->SetWidgetsLoweredState(false, WID_TE_DATE_BACKWARD, WID_TE_DATE_FORWARD, WIDGET_LIST_END);
01944 this->SetWidgetDirty(WID_TE_DATE_BACKWARD);
01945 this->SetWidgetDirty(WID_TE_DATE_FORWARD);
01946 }
01947
01948 virtual void OnTick()
01949 {
01950 if (this->IsWidgetLowered(WID_TE_PAUSE) != !!_pause_mode) {
01951 this->ToggleWidgetLoweredState(WID_TE_PAUSE);
01952 this->SetDirty();
01953 }
01954
01955 if (this->IsWidgetLowered(WID_TE_FAST_FORWARD) != !!_fast_forward) {
01956 this->ToggleWidgetLoweredState(WID_TE_FAST_FORWARD);
01957 this->SetDirty();
01958 }
01959 }
01960
01966 virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
01967 {
01968 if (!gui_scope) return;
01969 if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, WID_TE_ZOOM_IN, WID_TE_ZOOM_OUT);
01970 }
01971
01972 virtual void OnQueryTextFinished(char *str)
01973 {
01974
01975 if (str == NULL) return;
01976
01977 int32 value;
01978 if (!StrEmpty(str)) {
01979 value = atoi(str);
01980 } else {
01981
01982 value = DEF_START_YEAR;
01983 }
01984 _settings_game.game_creation.starting_year = Clamp(value, MIN_YEAR, MAX_YEAR);
01985 SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0);
01986
01987 this->SetDirty();
01988 }
01989
01990 static Hotkey<ScenarioEditorToolbarWindow> scenedit_maintoolbar_hotkeys[];
01991 };
01992
01993 Hotkey<ScenarioEditorToolbarWindow> ScenarioEditorToolbarWindow::scenedit_maintoolbar_hotkeys[] = {
01994 Hotkey<ScenarioEditorToolbarWindow>(_maintoolbar_pause_keys, "pause", MTEHK_PAUSE),
01995 Hotkey<ScenarioEditorToolbarWindow>((uint16)0, "fastforward", MTEHK_FASTFORWARD),
01996 Hotkey<ScenarioEditorToolbarWindow>(WKC_F2, "settings", MTEHK_SETTINGS),
01997 Hotkey<ScenarioEditorToolbarWindow>(WKC_F3, "saveload", MTEHK_SAVEGAME),
01998 Hotkey<ScenarioEditorToolbarWindow>(WKC_F4, "gen_land", MTEHK_GENLAND),
01999 Hotkey<ScenarioEditorToolbarWindow>(WKC_F5, "gen_town", MTEHK_GENTOWN),
02000 Hotkey<ScenarioEditorToolbarWindow>(WKC_F6, "gen_industry", MTEHK_GENINDUSTRY),
02001 Hotkey<ScenarioEditorToolbarWindow>(WKC_F7, "build_road", MTEHK_BUILD_ROAD),
02002 Hotkey<ScenarioEditorToolbarWindow>(WKC_F8, "build_docks", MTEHK_BUILD_DOCKS),
02003 Hotkey<ScenarioEditorToolbarWindow>(WKC_F9, "build_trees", MTEHK_BUILD_TREES),
02004 Hotkey<ScenarioEditorToolbarWindow>(WKC_F10, "build_sign", MTEHK_SIGN),
02005 Hotkey<ScenarioEditorToolbarWindow>(WKC_F11, "music", MTEHK_MUSIC),
02006 Hotkey<ScenarioEditorToolbarWindow>(WKC_F12, "land_info", MTEHK_LANDINFO),
02007 Hotkey<ScenarioEditorToolbarWindow>(WKC_CTRL | 'S', "small_screenshot", MTEHK_SMALL_SCREENSHOT),
02008 Hotkey<ScenarioEditorToolbarWindow>(WKC_CTRL | 'P', "zoomedin_screenshot", MTEHK_ZOOMEDIN_SCREENSHOT),
02009 Hotkey<ScenarioEditorToolbarWindow>(WKC_CTRL | 'D', "defaultzoom_screenshot", MTEHK_DEFAULTZOOM_SCREENSHOT),
02010 Hotkey<ScenarioEditorToolbarWindow>((uint16)0, "giant_screenshot", MTEHK_GIANT_SCREENSHOT),
02011 Hotkey<ScenarioEditorToolbarWindow>(_maintoolbar_zoomin_keys, "zoomin", MTEHK_ZOOM_IN),
02012 Hotkey<ScenarioEditorToolbarWindow>(_maintoolbar_zoomout_keys, "zoomout", MTEHK_ZOOM_OUT),
02013 Hotkey<ScenarioEditorToolbarWindow>('L', "terraform", MTEHK_TERRAFORM),
02014 Hotkey<ScenarioEditorToolbarWindow>('M', "smallmap", MTEHK_SMALLMAP),
02015 Hotkey<ScenarioEditorToolbarWindow>('V', "extra_viewport", MTEHK_EXTRA_VIEWPORT),
02016 HOTKEY_LIST_END(ScenarioEditorToolbarWindow)
02017 };
02018 Hotkey<ScenarioEditorToolbarWindow> *_scenedit_maintoolbar_hotkeys = ScenarioEditorToolbarWindow::scenedit_maintoolbar_hotkeys;
02019
02020 static const NWidgetPart _nested_toolb_scen_inner_widgets[] = {
02021 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_PAUSE), SetDataTip(SPR_IMG_PAUSE, STR_TOOLBAR_TOOLTIP_PAUSE_GAME),
02022 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_FAST_FORWARD), SetDataTip(SPR_IMG_FASTFORWARD, STR_TOOLBAR_TOOLTIP_FORWARD),
02023 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_SETTINGS), SetDataTip(SPR_IMG_SETTINGS, STR_TOOLBAR_TOOLTIP_OPTIONS),
02024 NWidget(WWT_IMGBTN_2, COLOUR_GREY, WID_TE_SAVE), SetDataTip(SPR_IMG_SAVE, STR_SCENEDIT_TOOLBAR_TOOLTIP_SAVE_SCENARIO_LOAD_SCENARIO),
02025 NWidget(NWID_SPACER),
02026 NWidget(WWT_PANEL, COLOUR_GREY, WID_TE_SPACER), EndContainer(),
02027 NWidget(NWID_SPACER),
02028 NWidget(WWT_PANEL, COLOUR_GREY, WID_TE_DATE_PANEL),
02029 NWidget(NWID_HORIZONTAL), SetPIP(3, 2, 3),
02030 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_DATE_BACKWARD), SetDataTip(SPR_ARROW_DOWN, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD),
02031 NWidget(WWT_EMPTY, COLOUR_GREY, WID_TE_DATE), SetDataTip(STR_NULL, STR_SCENEDIT_TOOLBAR_TOOLTIP_SET_DATE),
02032 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_DATE_FORWARD), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD),
02033 EndContainer(),
02034 EndContainer(),
02035 NWidget(NWID_SPACER),
02036 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_SMALL_MAP), SetDataTip(SPR_IMG_SMALLMAP, STR_SCENEDIT_TOOLBAR_TOOLTIP_DISPLAY_MAP_TOWN_DIRECTORY),
02037 NWidget(NWID_SPACER),
02038 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_ZOOM_IN), SetDataTip(SPR_IMG_ZOOMIN, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN),
02039 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_ZOOM_OUT), SetDataTip(SPR_IMG_ZOOMOUT, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT),
02040 NWidget(NWID_SPACER),
02041 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_LAND_GENERATE), SetDataTip(SPR_IMG_LANDSCAPING, STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION),
02042 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_TOWN_GENERATE), SetDataTip(SPR_IMG_TOWN, STR_SCENEDIT_TOOLBAR_TOWN_GENERATION),
02043 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_INDUSTRY), SetDataTip(SPR_IMG_INDUSTRY, STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION),
02044 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_ROADS), SetDataTip(SPR_IMG_BUILDROAD, STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION),
02045 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_WATER), SetDataTip(SPR_IMG_BUILDWATER, STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS),
02046 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_TREES), SetDataTip(SPR_IMG_PLANTTREES, STR_SCENEDIT_TOOLBAR_PLANT_TREES),
02047 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_SIGNS), SetDataTip(SPR_IMG_SIGN, STR_SCENEDIT_TOOLBAR_PLACE_SIGN),
02048 NWidget(NWID_SPACER),
02049 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_MUSIC_SOUND), SetDataTip(SPR_IMG_MUSIC, STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW),
02050 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_HELP), SetDataTip(SPR_IMG_QUERY, STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION),
02051 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_SWITCH_BAR), SetDataTip(SPR_IMG_SWITCH_TOOLBAR, STR_TOOLBAR_TOOLTIP_SWITCH_TOOLBAR),
02052 };
02053
02054 static NWidgetBase *MakeScenarioToolbar(int *biggest_index)
02055 {
02056 return MakeNWidgets(_nested_toolb_scen_inner_widgets, lengthof(_nested_toolb_scen_inner_widgets), biggest_index, new NWidgetScenarioToolbarContainer());
02057 }
02058
02059 static const NWidgetPart _nested_toolb_scen_widgets[] = {
02060 NWidgetFunction(MakeScenarioToolbar),
02061 };
02062
02063 static WindowDesc _toolb_scen_desc(
02064 WDP_MANUAL, 640, 22,
02065 WC_MAIN_TOOLBAR, WC_NONE,
02066 WDF_UNCLICK_BUTTONS | WDF_NO_FOCUS,
02067 _nested_toolb_scen_widgets, lengthof(_nested_toolb_scen_widgets)
02068 );
02069
02071 void AllocateToolbar()
02072 {
02073
02074 _last_built_roadtype = ROADTYPE_ROAD;
02075
02076 if (_game_mode == GM_EDITOR) {
02077 _preferred_toolbar_size = &_toolb_scen_desc.default_width;
02078 new ScenarioEditorToolbarWindow(&_toolb_scen_desc);
02079 } else {
02080 _preferred_toolbar_size = &_toolb_normal_desc.default_width;
02081 new MainToolbarWindow(&_toolb_normal_desc);
02082 }
02083 }