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