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