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