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