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