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