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