toolbar_gui.cpp

Go to the documentation of this file.
00001 /* $Id: toolbar_gui.cpp 16481 2009-05-31 12:18:03Z rubidium $ */
00002 
00005 #include "stdafx.h"
00006 #include "openttd.h"
00007 #include "gui.h"
00008 #include "window_gui.h"
00009 #include "window_func.h"
00010 #include "viewport_func.h"
00011 #include "command_func.h"
00012 #include "variables.h"
00013 #include "vehicle_gui.h"
00014 #include "rail_gui.h"
00015 #include "road_gui.h"
00016 #include "date_func.h"
00017 #include "vehicle_func.h"
00018 #include "sound_func.h"
00019 #include "terraform_gui.h"
00020 #include "transparency.h"
00021 #include "strings_func.h"
00022 #include "company_func.h"
00023 #include "company_gui.h"
00024 #include "vehicle_base.h"
00025 #include "cheat_func.h"
00026 #include "transparency_gui.h"
00027 #include "screenshot.h"
00028 #include "signs_func.h"
00029 #include "fios.h"
00030 #include "functions.h"
00031 #include "console_gui.h"
00032 #include "news_gui.h"
00033 #include "ai/ai_gui.hpp"
00034 #include "tilehighlight_func.h"
00035 #include "rail.h"
00036 #include "widgets/dropdown_type.h"
00037 #include "settings_type.h"
00038 #include "newgrf_config.h"
00039 
00040 #include "network/network.h"
00041 #include "network/network_gui.h"
00042 #include "network/network_func.h"
00043 
00044 #include "table/strings.h"
00045 #include "table/sprites.h"
00046 
00047 static void SplitToolbar(Window *w);
00048 
00049 RailType _last_built_railtype;
00050 RoadType _last_built_roadtype;
00051 
00053 enum ToolBarProperties {
00054   TBP_BUTTONWIDTH        =  22,  
00055   TBP_BUTTONHEIGHT       =  22,  
00056   TBP_DATEPANELWIDTH     = 130,  
00057 
00058   TBP_TOOLBAR_MINBUTTON  =  14,  
00059   TBP_NORMAL_MAXBUTTON   =  19,  
00060   TBP_SCENARIO_MAXBUTTON =  16,  
00061 };
00062 
00063 enum ToolbarMode {
00064   TB_NORMAL,
00065   TB_UPPER,
00066   TB_LOWER
00067 };
00068 
00069 enum ToolbarNormalWidgets {
00070   TBN_PAUSE         = 0,
00071   TBN_FASTFORWARD,
00072   TBN_SETTINGS,
00073   TBN_SAVEGAME,
00074   TBN_SMALLMAP,
00075   TBN_TOWNDIRECTORY,
00076   TBN_SUBSIDIES,
00077   TBN_STATIONS,
00078   TBN_FINANCES,
00079   TBN_COMPANIES,
00080   TBN_GRAPHICS,
00081   TBN_LEAGUE,
00082   TBN_INDUSTRIES,
00083   TBN_VEHICLESTART,      
00084   TBN_TRAINS        = TBN_VEHICLESTART,
00085   TBN_ROADVEHS,
00086   TBN_SHIPS,
00087   TBN_AIRCRAFTS,
00088   TBN_ZOOMIN,
00089   TBN_ZOOMOUT,
00090   TBN_RAILS,
00091   TBN_ROADS,
00092   TBN_WATER,
00093   TBN_AIR,
00094   TBN_LANDSCAPE,
00095   TBN_MUSICSOUND,
00096   TBN_NEWSREPORT,
00097   TBN_HELP,
00098   TBN_SWITCHBAR,         
00099 };
00100 
00101 enum ToolbarScenEditorWidgets {
00102   TBSE_PAUSE        = 0,
00103   TBSE_FASTFORWARD,
00104   TBSE_SAVESCENARIO = 3,
00105   TBSE_SPACERPANEL,
00106   TBSE_DATEPANEL,
00107   TBSE_DATEBACKWARD,
00108   TBSE_DATEFORWARD,
00109   TBSE_SMALLMAP,
00110   TBSE_ZOOMIN,
00111   TBSE_ZOOMOUT,
00112   TBSE_LANDGENERATE,
00113   TBSE_TOWNGENERATE,
00114   TBSE_INDUSTRYGENERATE,
00115   TBSE_BUILDROAD,
00116   TBSE_BUILDDOCKS,
00117   TBSE_PLANTTREES,
00118   TBSE_PLACESIGNS,
00119 };
00120 
00124 class DropDownListCheckedItem : public DropDownListStringItem {
00125 public:
00126   bool checked;
00127 
00128   DropDownListCheckedItem(StringID string, int result, bool masked, bool checked) : DropDownListStringItem(string, result, masked), checked(checked) {}
00129 
00130   virtual ~DropDownListCheckedItem() {}
00131 
00132   void Draw(int x, int y, uint width, uint height, bool sel, int bg_colour) const
00133   {
00134     if (checked) {
00135       DrawString(x + 2, y, STR_CHECKMARK, sel ? TC_WHITE : TC_BLACK);
00136     }
00137     DrawStringTruncated(x + 2, y, this->String(), sel ? TC_WHITE : TC_BLACK, width);
00138   }
00139 };
00140 
00144 class DropDownListCompanyItem : public DropDownListItem {
00145 public:
00146   bool greyed;
00147 
00148   DropDownListCompanyItem(int result, bool masked, bool greyed) : DropDownListItem(result, masked), greyed(greyed) {}
00149 
00150   virtual ~DropDownListCompanyItem() {}
00151 
00152   bool Selectable() const
00153   {
00154     return true;
00155   }
00156 
00157   uint Width() const
00158   {
00159     char buffer[512];
00160     CompanyID company = (CompanyID)result;
00161     SetDParam(0, company);
00162     SetDParam(1, company);
00163     GetString(buffer, STR_7021, lastof(buffer));
00164     return GetStringBoundingBox(buffer).width + 19;
00165   }
00166 
00167   void Draw(int x, int y, uint width, uint height, bool sel, int bg_colour) const
00168   {
00169     CompanyID company = (CompanyID)result;
00170 
00171     /* It's possible the company is deleted while the dropdown is open */
00172     if (!IsValidCompanyID(company)) return;
00173 
00174     DrawCompanyIcon(company, x + 2, y + 1);
00175 
00176     SetDParam(0, company);
00177     SetDParam(1, company);
00178     TextColour col;
00179     if (this->greyed) {
00180       col = TC_GREY;
00181     } else {
00182       col = sel ? TC_WHITE : TC_BLACK;
00183     }
00184     DrawStringTruncated(x + 19, y, STR_7021, col, width - 17);
00185   }
00186 };
00187 
00191 static void PopupMainToolbMenu(Window *w, int widget, StringID string, int count)
00192 {
00193   DropDownList *list = new DropDownList();
00194   for (int i = 0; i < count; i++) {
00195     list->push_back(new DropDownListStringItem(string + i, i, false));
00196   }
00197   ShowDropDownList(w, list, 0, widget, 140, true, true);
00198   SndPlayFx(SND_15_BEEP);
00199 }
00200 
00202 enum {
00203   CTMN_CLIENT_LIST = -1, 
00204   CTMN_NEW_COMPANY = -2, 
00205   CTMN_SPECTATE    = -3, 
00206 };
00207 
00211 static void PopupMainCompanyToolbMenu(Window *w, int widget, int grey = 0)
00212 {
00213   DropDownList *list = new DropDownList();
00214 
00215 #ifdef ENABLE_NETWORK
00216   if (widget == TBN_COMPANIES && _networking) {
00217     /* Add the client list button for the companies menu */
00218     list->push_back(new DropDownListStringItem(STR_NETWORK_CLIENT_LIST, CTMN_CLIENT_LIST, false));
00219 
00220     if (_local_company == COMPANY_SPECTATOR) {
00221       list->push_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_NEW_COMPANY, CTMN_NEW_COMPANY, NetworkMaxCompaniesReached()));
00222     } else {
00223       list->push_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_SPECTATE, CTMN_SPECTATE, NetworkMaxSpectatorsReached()));
00224     }
00225   }
00226 #endif /* ENABLE_NETWORK */
00227 
00228   for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
00229     if (!IsValidCompanyID(c)) continue;
00230     list->push_back(new DropDownListCompanyItem(c, false, HasBit(grey, c)));
00231   }
00232 
00233   ShowDropDownList(w, list, _local_company == COMPANY_SPECTATOR ? CTMN_CLIENT_LIST : (int)_local_company, widget, 240, true, true);
00234   SndPlayFx(SND_15_BEEP);
00235 }
00236 
00237 
00238 static ToolbarMode _toolbar_mode;
00239 
00240 static void SelectSignTool()
00241 {
00242   if (_cursor.sprite == SPR_CURSOR_SIGN) {
00243     ResetObjectToPlace();
00244   } else {
00245     SetObjectToPlace(SPR_CURSOR_SIGN, PAL_NONE, VHM_RECT, WC_MAIN_TOOLBAR, 0);
00246     _place_proc = PlaceProc_Sign;
00247   }
00248 }
00249 
00250 /* --- Pausing --- */
00251 
00252 static void ToolbarPauseClick(Window *w)
00253 {
00254   if (_networking && !_network_server) return; // only server can pause the game
00255 
00256   if (DoCommandP(0, _pause_game ? 0 : 1, 0, CMD_PAUSE)) SndPlayFx(SND_15_BEEP);
00257 }
00258 
00259 /* --- Fast forwarding --- */
00260 
00261 static void ToolbarFastForwardClick(Window *w)
00262 {
00263   _fast_forward ^= true;
00264   SndPlayFx(SND_15_BEEP);
00265 }
00266 
00267 /* --- Options button menu --- */
00268 
00269 enum OptionMenuEntries {
00270   OME_GAMEOPTIONS,
00271   OME_DIFFICULTIES,
00272   OME_SETTINGS,
00273   OME_NEWGRFSETTINGS,
00274   OME_TRANSPARENCIES,
00275   OME_SHOW_TOWNNAMES,
00276   OME_SHOW_STATIONNAMES,
00277   OME_SHOW_SIGNS,
00278   OME_SHOW_WAYPOINTNAMES,
00279   OME_FULL_ANIMATION,
00280   OME_FULL_DETAILS,
00281   OME_TRANSPARENTBUILDINGS,
00282   OME_SHOW_STATIONSIGNS,
00283 };
00284 
00285 static void ToolbarOptionsClick(Window *w)
00286 {
00287   DropDownList *list = new DropDownList();
00288   list->push_back(new DropDownListStringItem(STR_02C4_GAME_OPTIONS,        OME_GAMEOPTIONS, false));
00289   list->push_back(new DropDownListStringItem(STR_02C6_DIFFICULTY_SETTINGS, OME_DIFFICULTIES, false));
00290   list->push_back(new DropDownListStringItem(STR_MENU_CONFIG_SETTINGS,      OME_SETTINGS, false));
00291   list->push_back(new DropDownListStringItem(STR_NEWGRF_SETTINGS,          OME_NEWGRFSETTINGS, false));
00292   list->push_back(new DropDownListStringItem(STR_TRANSPARENCY_OPTIONS,     OME_TRANSPARENCIES, false));
00293   list->push_back(new DropDownListItem(-1, false));
00294   list->push_back(new DropDownListCheckedItem(STR_02CA_TOWN_NAMES_DISPLAYED,    OME_SHOW_TOWNNAMES, false, HasBit(_display_opt, DO_SHOW_TOWN_NAMES)));
00295   list->push_back(new DropDownListCheckedItem(STR_02CC_STATION_NAMES_DISPLAYED, OME_SHOW_STATIONNAMES, false, HasBit(_display_opt, DO_SHOW_STATION_NAMES)));
00296   list->push_back(new DropDownListCheckedItem(STR_02CE_SIGNS_DISPLAYED,         OME_SHOW_SIGNS, false, HasBit(_display_opt, DO_SHOW_SIGNS)));
00297   list->push_back(new DropDownListCheckedItem(STR_WAYPOINTS_DISPLAYED2,         OME_SHOW_WAYPOINTNAMES, false, HasBit(_display_opt, DO_WAYPOINTS)));
00298   list->push_back(new DropDownListCheckedItem(STR_02D0_FULL_ANIMATION,          OME_FULL_ANIMATION, false, HasBit(_display_opt, DO_FULL_ANIMATION)));
00299   list->push_back(new DropDownListCheckedItem(STR_02D2_FULL_DETAIL,             OME_FULL_DETAILS, false, HasBit(_display_opt, DO_FULL_DETAIL)));
00300   list->push_back(new DropDownListCheckedItem(STR_02D4_TRANSPARENT_BUILDINGS,   OME_TRANSPARENTBUILDINGS, false, IsTransparencySet(TO_HOUSES)));
00301   list->push_back(new DropDownListCheckedItem(STR_TRANSPARENT_SIGNS,            OME_SHOW_STATIONSIGNS, false, IsTransparencySet(TO_SIGNS)));
00302 
00303   ShowDropDownList(w, list, 0, TBN_SETTINGS, 140, true, true);
00304   SndPlayFx(SND_15_BEEP);
00305 }
00306 
00307 static void MenuClickSettings(int index)
00308 {
00309   switch (index) {
00310     case OME_GAMEOPTIONS:          ShowGameOptions();                              return;
00311     case OME_DIFFICULTIES:         ShowGameDifficulty();                           return;
00312     case OME_SETTINGS:             ShowGameSettings();                             return;
00313     case OME_NEWGRFSETTINGS:       ShowNewGRFSettings(!_networking, true, true, &_grfconfig);   return;
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_SIGNS:           ToggleBit(_display_opt, DO_SHOW_SIGNS);         break;
00319     case OME_SHOW_WAYPOINTNAMES:   ToggleBit(_display_opt, DO_WAYPOINTS);          break;
00320     case OME_FULL_ANIMATION:       ToggleBit(_display_opt, DO_FULL_ANIMATION);     break;
00321     case OME_FULL_DETAILS:         ToggleBit(_display_opt, DO_FULL_DETAIL);        break;
00322     case OME_TRANSPARENTBUILDINGS: ToggleTransparency(TO_HOUSES);                  break;
00323     case OME_SHOW_STATIONSIGNS:    ToggleTransparency(TO_SIGNS);                   break;
00324   }
00325   MarkWholeScreenDirty();
00326 }
00327 
00328 /* --- Saving/loading button menu --- */
00329 
00330 enum SaveLoadEditorMenuEntries {
00331   SLEME_SAVE_SCENARIO   = 0,
00332   SLEME_LOAD_SCENARIO,
00333   SLEME_LOAD_HEIGHTMAP,
00334   SLEME_EXIT_TOINTRO,
00335   SLEME_EXIT_GAME       = 5,
00336   SLEME_MENUCOUNT,
00337 };
00338 
00339 enum SaveLoadNormalMenuEntries {
00340   SLNME_SAVE_GAME   = 0,
00341   SLNME_LOAD_GAME,
00342   SLNME_EXIT_TOINTRO,
00343   SLNME_EXIT_GAME,
00344   SLNME_MENUCOUNT,
00345 };
00346 
00347 static void ToolbarSaveClick(Window *w)
00348 {
00349   PopupMainToolbMenu(w, TBN_SAVEGAME, STR_015C_SAVE_GAME, SLNME_MENUCOUNT);
00350 }
00351 
00352 static void ToolbarScenSaveOrLoad(Window *w)
00353 {
00354   PopupMainToolbMenu(w, TBSE_SAVESCENARIO, STR_0292_SAVE_SCENARIO, SLEME_MENUCOUNT);
00355 }
00356 
00357 static void MenuClickSaveLoad(int index = 0)
00358 {
00359   if (_game_mode == GM_EDITOR) {
00360     switch (index) {
00361       case SLEME_SAVE_SCENARIO:  ShowSaveLoadDialog(SLD_SAVE_SCENARIO);  break;
00362       case SLEME_LOAD_SCENARIO:  ShowSaveLoadDialog(SLD_LOAD_SCENARIO);  break;
00363       case SLEME_LOAD_HEIGHTMAP: ShowSaveLoadDialog(SLD_LOAD_HEIGHTMAP); break;
00364       case SLEME_EXIT_TOINTRO:   AskExitToGameMenu();                    break;
00365       case SLEME_EXIT_GAME:      HandleExitGameRequest();                break;
00366     }
00367   } else {
00368     switch (index) {
00369       case SLNME_SAVE_GAME:      ShowSaveLoadDialog(SLD_SAVE_GAME); break;
00370       case SLNME_LOAD_GAME:      ShowSaveLoadDialog(SLD_LOAD_GAME); break;
00371       case SLNME_EXIT_TOINTRO:   AskExitToGameMenu();               break;
00372       case SLNME_EXIT_GAME:      HandleExitGameRequest();           break;
00373     }
00374   }
00375 }
00376 
00377 /* --- Map button menu --- */
00378 
00379 enum MapMenuEntries {
00380   MME_SHOW_SMALLMAP        = 0,
00381   MME_SHOW_EXTRAVIEWPORTS,
00382   MME_SHOW_SIGNLISTS,
00383   MME_SHOW_TOWNDIRECTORY,    
00384   MME_MENUCOUNT_NORMAL     = 3,
00385   MME_MENUCOUNT_EDITOR     = 4,
00386 };
00387 
00388 static void ToolbarMapClick(Window *w)
00389 {
00390   PopupMainToolbMenu(w, TBN_SMALLMAP, STR_02DE_MAP_OF_WORLD, MME_MENUCOUNT_NORMAL);
00391 }
00392 
00393 static void ToolbarScenMapTownDir(Window *w)
00394 {
00395   PopupMainToolbMenu(w, TBSE_SMALLMAP, STR_02DE_MAP_OF_WORLD, MME_MENUCOUNT_EDITOR);
00396 }
00397 
00398 static void MenuClickMap(int index)
00399 {
00400   switch (index) {
00401     case MME_SHOW_SMALLMAP:       ShowSmallMap();            break;
00402     case MME_SHOW_EXTRAVIEWPORTS: ShowExtraViewPortWindow(); break;
00403     case MME_SHOW_SIGNLISTS:      ShowSignList();            break;
00404     case MME_SHOW_TOWNDIRECTORY:  if (_game_mode == GM_EDITOR) ShowTownDirectory(); break;
00405   }
00406 }
00407 
00408 /* --- Town button menu --- */
00409 
00410 static void ToolbarTownClick(Window *w)
00411 {
00412   PopupMainToolbMenu(w, TBN_TOWNDIRECTORY, STR_02BB_TOWN_DIRECTORY, 1);
00413 }
00414 
00415 static void MenuClickTown(int index)
00416 {
00417   ShowTownDirectory();
00418 }
00419 
00420 /* --- Subidies button menu --- */
00421 
00422 static void ToolbarSubsidiesClick(Window *w)
00423 {
00424   PopupMainToolbMenu(w, TBN_SUBSIDIES, STR_02DD_SUBSIDIES, 1);
00425 }
00426 
00427 static void MenuClickSubsidies(int index)
00428 {
00429   ShowSubsidiesList();
00430 }
00431 
00432 /* --- Stations button menu --- */
00433 
00434 static void ToolbarStationsClick(Window *w)
00435 {
00436   PopupMainCompanyToolbMenu(w, TBN_STATIONS);
00437 }
00438 
00439 static void MenuClickStations(int index)
00440 {
00441   ShowCompanyStations((CompanyID)index);
00442 }
00443 
00444 /* --- Finances button menu --- */
00445 
00446 static void ToolbarFinancesClick(Window *w)
00447 {
00448   PopupMainCompanyToolbMenu(w, TBN_FINANCES);
00449 }
00450 
00451 static void MenuClickFinances(int index)
00452 {
00453   ShowCompanyFinances((CompanyID)index);
00454 }
00455 
00456 /* --- Company's button menu --- */
00457 
00458 static void ToolbarCompaniesClick(Window *w)
00459 {
00460   PopupMainCompanyToolbMenu(w, TBN_COMPANIES);
00461 }
00462 
00463 static void MenuClickCompany(int index)
00464 {
00465 #ifdef ENABLE_NETWORK
00466   if (_networking) {
00467     switch (index) {
00468       case CTMN_CLIENT_LIST:
00469         ShowClientList();
00470         return;
00471 
00472       case CTMN_NEW_COMPANY:
00473         if (_network_server) {
00474           DoCommandP(0, 0, _network_own_client_id, CMD_COMPANY_CTRL);
00475         } else {
00476           NetworkSend_Command(0, 0, 0, CMD_COMPANY_CTRL, NULL, NULL);
00477         }
00478         return;
00479 
00480       case CTMN_SPECTATE:
00481         if (_network_server) {
00482           NetworkServerDoMove(CLIENT_ID_SERVER, COMPANY_SPECTATOR);
00483           MarkWholeScreenDirty();
00484         } else {
00485           NetworkClientRequestMove(COMPANY_SPECTATOR);
00486         }
00487         return;
00488     }
00489   }
00490 #endif /* ENABLE_NETWORK */
00491   ShowCompany((CompanyID)index);
00492 }
00493 
00494 /* --- Graphs button menu --- */
00495 
00496 static void ToolbarGraphsClick(Window *w)
00497 {
00498   PopupMainToolbMenu(w, TBN_GRAPHICS, STR_0154_OPERATING_PROFIT_GRAPH, (_toolbar_mode == TB_NORMAL) ? 6 : 8);
00499 }
00500 
00501 static void MenuClickGraphs(int index)
00502 {
00503   switch (index) {
00504     case 0: ShowOperatingProfitGraph();    break;
00505     case 1: ShowIncomeGraph();             break;
00506     case 2: ShowDeliveredCargoGraph();     break;
00507     case 3: ShowPerformanceHistoryGraph(); break;
00508     case 4: ShowCompanyValueGraph();       break;
00509     case 5: ShowCargoPaymentRates();       break;
00510     /* functions for combined graphs/league button */
00511     case 6: ShowCompanyLeagueTable();      break;
00512     case 7: ShowPerformanceRatingDetail(); break;
00513   }
00514 }
00515 
00516 /* --- League button menu --- */
00517 
00518 static void ToolbarLeagueClick(Window *w)
00519 {
00520   PopupMainToolbMenu(w, TBN_LEAGUE, STR_015A_COMPANY_LEAGUE_TABLE, 2);
00521 }
00522 
00523 static void MenuClickLeague(int index)
00524 {
00525   switch (index) {
00526     case 0: ShowCompanyLeagueTable();      break;
00527     case 1: ShowPerformanceRatingDetail(); break;
00528   }
00529 }
00530 
00531 /* --- Industries button menu --- */
00532 
00533 static void ToolbarIndustryClick(Window *w)
00534 {
00535   /* Disable build-industry menu if we are a spectator */
00536   PopupMainToolbMenu(w, TBN_INDUSTRIES, STR_INDUSTRY_DIR, (_local_company == COMPANY_SPECTATOR) ? 1 : 2);
00537 }
00538 
00539 static void MenuClickIndustry(int index)
00540 {
00541   switch (index) {
00542     case 0: ShowIndustryDirectory();   break;
00543     case 1: ShowBuildIndustryWindow(); break;
00544   }
00545 }
00546 
00547 /* --- Trains button menu + 1 helper function for all vehicles. --- */
00548 
00549 static void ToolbarVehicleClick(Window *w, VehicleType veh)
00550 {
00551   const Vehicle *v;
00552   int dis = ~0;
00553 
00554   FOR_ALL_VEHICLES(v) {
00555     if (v->type == veh && v->IsPrimaryVehicle()) ClrBit(dis, v->owner);
00556   }
00557   PopupMainCompanyToolbMenu(w, TBN_VEHICLESTART + veh, dis);
00558 }
00559 
00560 
00561 static void ToolbarTrainClick(Window *w)
00562 {
00563   ToolbarVehicleClick(w, VEH_TRAIN);
00564 }
00565 
00566 static void MenuClickShowTrains(int index)
00567 {
00568   ShowVehicleListWindow((CompanyID)index, VEH_TRAIN);
00569 }
00570 
00571 /* --- Road vehicle button menu --- */
00572 
00573 static void ToolbarRoadClick(Window *w)
00574 {
00575   ToolbarVehicleClick(w, VEH_ROAD);
00576 }
00577 
00578 static void MenuClickShowRoad(int index)
00579 {
00580   ShowVehicleListWindow((CompanyID)index, VEH_ROAD);
00581 }
00582 
00583 /* --- Ship button menu --- */
00584 
00585 static void ToolbarShipClick(Window *w)
00586 {
00587   ToolbarVehicleClick(w, VEH_SHIP);
00588 }
00589 
00590 static void MenuClickShowShips(int index)
00591 {
00592   ShowVehicleListWindow((CompanyID)index, VEH_SHIP);
00593 }
00594 
00595 /* --- Aircraft button menu --- */
00596 
00597 static void ToolbarAirClick(Window *w)
00598 {
00599   ToolbarVehicleClick(w, VEH_AIRCRAFT);
00600 }
00601 
00602 static void MenuClickShowAir(int index)
00603 {
00604   ShowVehicleListWindow((CompanyID)index, VEH_AIRCRAFT);
00605 }
00606 
00607 /* --- Zoom in button --- */
00608 
00609 static void ToolbarZoomInClick(Window *w)
00610 {
00611   if (DoZoomInOutWindow(ZOOM_IN, FindWindowById(WC_MAIN_WINDOW, 0))) {
00612     w->HandleButtonClick((_game_mode == GM_EDITOR) ? (byte)TBSE_ZOOMIN : (byte)TBN_ZOOMIN);
00613     SndPlayFx(SND_15_BEEP);
00614   }
00615 }
00616 
00617 /* --- Zoom out button --- */
00618 
00619 static void ToolbarZoomOutClick(Window *w)
00620 {
00621   if (DoZoomInOutWindow(ZOOM_OUT, FindWindowById(WC_MAIN_WINDOW, 0))) {
00622     w->HandleButtonClick((_game_mode == GM_EDITOR) ? (byte)TBSE_ZOOMOUT : (byte)TBN_ZOOMOUT);
00623     SndPlayFx(SND_15_BEEP);
00624   }
00625 }
00626 
00627 /* --- Rail button menu --- */
00628 
00629 static void ToolbarBuildRailClick(Window *w)
00630 {
00631   const Company *c = GetCompany(_local_company);
00632   DropDownList *list = new DropDownList();
00633   for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
00634     const RailtypeInfo *rti = GetRailTypeInfo(rt);
00635     /* Skip rail type if it has no label */
00636     if (rti->label == 0) continue;
00637     list->push_back(new DropDownListStringItem(rti->strings.menu_text, rt, !HasBit(c->avail_railtypes, rt)));
00638   }
00639   ShowDropDownList(w, list, _last_built_railtype, TBN_RAILS, 140, true, true);
00640   SndPlayFx(SND_15_BEEP);
00641 }
00642 
00643 static void MenuClickBuildRail(int index)
00644 {
00645   _last_built_railtype = (RailType)index;
00646   ShowBuildRailToolbar(_last_built_railtype, -1);
00647 }
00648 
00649 /* --- Road button menu --- */
00650 
00651 static void ToolbarBuildRoadClick(Window *w)
00652 {
00653   const Company *c = GetCompany(_local_company);
00654   DropDownList *list = new DropDownList();
00655   for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
00656     /* The standard road button is *always* available */
00657     list->push_back(new DropDownListStringItem(STR_180A_ROAD_CONSTRUCTION + rt, rt, !(HasBit(c->avail_roadtypes, rt) || rt == ROADTYPE_ROAD)));
00658   }
00659   ShowDropDownList(w, list, _last_built_roadtype, TBN_ROADS, 140, true, true);
00660   SndPlayFx(SND_15_BEEP);
00661 }
00662 
00663 static void MenuClickBuildRoad(int index)
00664 {
00665   _last_built_roadtype = (RoadType)index;
00666   ShowBuildRoadToolbar(_last_built_roadtype);
00667 }
00668 
00669 /* --- Water button menu --- */
00670 
00671 static void ToolbarBuildWaterClick(Window *w)
00672 {
00673   PopupMainToolbMenu(w, TBN_WATER, STR_9800_WATERWAYS_CONSTRUCTION, 1);
00674 }
00675 
00676 static void MenuClickBuildWater(int index)
00677 {
00678   ShowBuildDocksToolbar();
00679 }
00680 
00681 /* --- Airport button menu --- */
00682 
00683 static void ToolbarBuildAirClick(Window *w)
00684 {
00685   PopupMainToolbMenu(w, TBN_AIR, STR_A01D_AIRPORT_CONSTRUCTION, 1);
00686 }
00687 
00688 static void MenuClickBuildAir(int index)
00689 {
00690   ShowBuildAirToolbar();
00691 }
00692 
00693 /* --- Forest button menu --- */
00694 
00695 static void ToolbarForestClick(Window *w)
00696 {
00697   PopupMainToolbMenu(w, TBN_LANDSCAPE, STR_LANDSCAPING, 3);
00698 }
00699 
00700 static void MenuClickForest(int index)
00701 {
00702   switch (index) {
00703     case 0: ShowTerraformToolbar();  break;
00704     case 1: ShowBuildTreesToolbar(); break;
00705     case 2: SelectSignTool();        break;
00706   }
00707 }
00708 
00709 /* --- Music button menu --- */
00710 
00711 static void ToolbarMusicClick(Window *w)
00712 {
00713   PopupMainToolbMenu(w, TBN_MUSICSOUND, STR_01D3_SOUND_MUSIC, 1);
00714 }
00715 
00716 static void MenuClickMusicWindow(int index)
00717 {
00718   ShowMusicWindow();
00719 }
00720 
00721 /* --- Newspaper button menu --- */
00722 
00723 static void ToolbarNewspaperClick(Window *w)
00724 {
00725   PopupMainToolbMenu(w, TBN_NEWSREPORT, STR_0200_LAST_MESSAGE_NEWS_REPORT, 3);
00726 }
00727 
00728 static void MenuClickNewspaper(int index)
00729 {
00730   switch (index) {
00731     case 0: ShowLastNewsMessage(); break;
00732     case 1: ShowMessageOptions();  break;
00733     case 2: ShowMessageHistory();  break;
00734   }
00735 }
00736 
00737 /* --- Help button menu --- */
00738 
00739 static void ToolbarHelpClick(Window *w)
00740 {
00741   PopupMainToolbMenu(w, TBN_HELP, STR_02D5_LAND_BLOCK_INFO, 7);
00742 }
00743 
00744 static void MenuClickSmallScreenshot()
00745 {
00746   SetScreenshotType(SC_VIEWPORT);
00747 }
00748 
00749 static void MenuClickWorldScreenshot()
00750 {
00751   SetScreenshotType(SC_WORLD);
00752 }
00753 
00754 static void MenuClickHelp(int index)
00755 {
00756   switch (index) {
00757     case 0: PlaceLandBlockInfo();       break;
00758     case 2: IConsoleSwitch();           break;
00759     case 3: ShowAIDebugWindow();        break;
00760     case 4: MenuClickSmallScreenshot(); break;
00761     case 5: MenuClickWorldScreenshot(); break;
00762     case 6: ShowAboutWindow();          break;
00763   }
00764 }
00765 
00766 /* --- Switch toolbar button --- */
00767 
00768 static void ToolbarSwitchClick(Window *w)
00769 {
00770   if (_toolbar_mode != TB_LOWER) {
00771     _toolbar_mode = TB_LOWER;
00772   } else {
00773     _toolbar_mode = TB_UPPER;
00774   }
00775 
00776   SplitToolbar(w);
00777   w->HandleButtonClick(TBN_SWITCHBAR);
00778   SetWindowDirty(w);
00779   SndPlayFx(SND_15_BEEP);
00780 }
00781 
00782 /* --- Scenario editor specific handlers. */
00783 
00784 static void ToolbarScenDateBackward(Window *w)
00785 {
00786   /* don't allow too fast scrolling */
00787   if ((w->flags4 & WF_TIMEOUT_MASK) <= WF_TIMEOUT_TRIGGER) {
00788     w->HandleButtonClick(TBSE_DATEBACKWARD);
00789     w->SetDirty();
00790 
00791     _settings_game.game_creation.starting_year = Clamp(_settings_game.game_creation.starting_year - 1, MIN_YEAR, MAX_YEAR);
00792     SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
00793   }
00794   _left_button_clicked = false;
00795 }
00796 
00797 static void ToolbarScenDateForward(Window *w)
00798 {
00799   /* don't allow too fast scrolling */
00800   if ((w->flags4 & WF_TIMEOUT_MASK) <= WF_TIMEOUT_TRIGGER) {
00801     w->HandleButtonClick(TBSE_DATEFORWARD);
00802     w->SetDirty();
00803 
00804     _settings_game.game_creation.starting_year = Clamp(_settings_game.game_creation.starting_year + 1, MIN_YEAR, MAX_YEAR);
00805     SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
00806   }
00807   _left_button_clicked = false;
00808 }
00809 
00810 static void ToolbarScenGenLand(Window *w)
00811 {
00812   w->HandleButtonClick(TBSE_LANDGENERATE);
00813   SndPlayFx(SND_15_BEEP);
00814 
00815   ShowEditorTerraformToolbar();
00816 }
00817 
00818 
00819 static void ToolbarScenGenTown(Window *w)
00820 {
00821   w->HandleButtonClick(TBSE_TOWNGENERATE);
00822   SndPlayFx(SND_15_BEEP);
00823   ShowBuildTownWindow();
00824 }
00825 
00826 static void ToolbarScenGenIndustry(Window *w)
00827 {
00828   w->HandleButtonClick(TBSE_INDUSTRYGENERATE);
00829   SndPlayFx(SND_15_BEEP);
00830   ShowBuildIndustryWindow();
00831 }
00832 
00833 static void ToolbarScenBuildRoad(Window *w)
00834 {
00835   w->HandleButtonClick(TBSE_BUILDROAD);
00836   SndPlayFx(SND_15_BEEP);
00837   ShowBuildRoadScenToolbar();
00838 }
00839 
00840 static void ToolbarScenBuildDocks(Window *w)
00841 {
00842   w->HandleButtonClick(TBSE_BUILDDOCKS);
00843   SndPlayFx(SND_15_BEEP);
00844   ShowBuildDocksScenToolbar();
00845 }
00846 
00847 static void ToolbarScenPlantTrees(Window *w)
00848 {
00849   w->HandleButtonClick(TBSE_PLANTTREES);
00850   SndPlayFx(SND_15_BEEP);
00851   ShowBuildTreesToolbar();
00852 }
00853 
00854 static void ToolbarScenPlaceSign(Window *w)
00855 {
00856   w->HandleButtonClick(TBSE_PLACESIGNS);
00857   SndPlayFx(SND_15_BEEP);
00858   SelectSignTool();
00859 }
00860 
00861 static void ToolbarBtn_NULL(Window *w)
00862 {
00863 }
00864 
00865 /* --- Resizing the toolbar */
00866 
00867 static void ResizeToolbar(Window *w)
00868 {
00869   /* There are 27 buttons plus some spacings if the space allows it */
00870   uint button_width;
00871   uint spacing;
00872   uint widgetcount = w->widget_count - 1;
00873 
00874   if (w->width >= (int)widgetcount * TBP_BUTTONWIDTH) {
00875     button_width = TBP_BUTTONWIDTH;
00876     spacing = w->width - (widgetcount * button_width);
00877   } else {
00878     button_width = w->width / widgetcount;
00879     spacing = 0;
00880   }
00881 
00882   static const uint extra_spacing_at[] = { 4, 8, 13, 17, 19, 24, 0 };
00883   uint i = 0;
00884   for (uint x = 0, j = 0; i < widgetcount; i++) {
00885     if (extra_spacing_at[j] == i) {
00886       j++;
00887       uint add = spacing / (lengthof(extra_spacing_at) - j);
00888       spacing -= add;
00889       x += add;
00890     }
00891 
00892     w->widget[i].type = WWT_IMGBTN;
00893     w->widget[i].left = x;
00894     x += (spacing != 0) ? button_width : (w->width - x) / (widgetcount - i);
00895     w->widget[i].right = x - 1;
00896   }
00897 
00898   w->widget[i].type = WWT_EMPTY; // i now points to the last item
00899   _toolbar_mode = TB_NORMAL;
00900 }
00901 
00902 /* --- Split the toolbar */
00903 
00904 static void SplitToolbar(Window *w)
00905 {
00906   static const byte arrange14[] = {
00907     0,  1, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 27,
00908     2,  3,  4,  5,  6,  7,  8,  9, 10, 12, 24, 25, 26, 27,
00909   };
00910   static const byte arrange15[] = {
00911     0,  1,  4, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
00912     0,  2,  4,  3,  5,  6,  7,  8,  9, 10, 12, 24, 25, 26, 27,
00913   };
00914   static const byte arrange16[] = {
00915     0,  1,  2,  4, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
00916     0,  1,  3,  5,  6,  7,  8,  9, 10, 12, 24, 25, 26, 17, 18, 27,
00917   };
00918   static const byte arrange17[] = {
00919     0,  1,  2,  4,  6, 13, 14, 15, 16, 19, 20, 21, 22, 23, 17, 18, 27,
00920     0,  1,  3,  4,  6,  5,  7,  8,  9, 10, 12, 24, 25, 26, 17, 18, 27,
00921   };
00922   static const byte arrange18[] = {
00923     0,  1,  2,  4,  5,  6,  7,  8,  9, 12, 19, 20, 21, 22, 23, 17, 18, 27,
00924     0,  1,  3,  4,  5,  6,  7, 10, 13, 14, 15, 16, 24, 25, 26, 17, 18, 27,
00925   };
00926   static const byte arrange19[] = {
00927     0,  1,  2,  4,  5,  6, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 17, 18, 27,
00928     0,  1,  3,  4,  7,  8,  9, 10, 12, 25, 19, 20, 21, 22, 23, 26, 17, 18, 27,
00929   };
00930 
00931   static const byte *arrangements[] = { arrange14, arrange15, arrange16, arrange17, arrange18, arrange19 };
00932 
00933   uint max_icons = max(TBP_TOOLBAR_MINBUTTON, (ToolBarProperties)((w->width + TBP_BUTTONWIDTH / 2) / TBP_BUTTONWIDTH));
00934 
00935   assert(max_icons >= TBP_TOOLBAR_MINBUTTON && max_icons <= TBP_NORMAL_MAXBUTTON);
00936 
00937   /* first hide all icons */
00938   for (uint i = 0; i < w->widget_count - 1; i++) {
00939     w->widget[i].type = WWT_EMPTY;
00940   }
00941 
00942   /* now activate them all on their proper positions */
00943   for (uint i = 0, x = 0, n = max_icons - TBP_TOOLBAR_MINBUTTON; i < max_icons; i++) {
00944     uint icon = arrangements[n][i + ((_toolbar_mode == TB_LOWER) ? max_icons : 0)];
00945     w->widget[icon].type = WWT_IMGBTN;
00946     w->widget[icon].left = x;
00947     x += (w->width - x) / (max_icons - i);
00948     w->widget[icon].right = x - 1;
00949   }
00950 }
00951 
00952 typedef void MenuClickedProc(int index);
00953 
00954 static MenuClickedProc * const _menu_clicked_procs[] = {
00955   NULL,                 // 0
00956   NULL,                 // 1
00957   MenuClickSettings,    // 2
00958   MenuClickSaveLoad,    // 3
00959   MenuClickMap,         // 4
00960   MenuClickTown,        // 5
00961   MenuClickSubsidies,   // 6
00962   MenuClickStations,    // 7
00963   MenuClickFinances,    // 8
00964   MenuClickCompany,     // 9
00965   MenuClickGraphs,      // 10
00966   MenuClickLeague,      // 11
00967   MenuClickIndustry,    // 12
00968   MenuClickShowTrains,  // 13
00969   MenuClickShowRoad,    // 14
00970   MenuClickShowShips,   // 15
00971   MenuClickShowAir,     // 16
00972   MenuClickMap,         // 17
00973   NULL,                 // 18
00974   MenuClickBuildRail,   // 19
00975   MenuClickBuildRoad,   // 20
00976   MenuClickBuildWater,  // 21
00977   MenuClickBuildAir,    // 22
00978   MenuClickForest,      // 23
00979   MenuClickMusicWindow, // 24
00980   MenuClickNewspaper,   // 25
00981   MenuClickHelp,        // 26
00982 };
00983 
00984 /* --- Toolbar handling for the 'normal' case */
00985 
00986 typedef void ToolbarButtonProc(Window *w);
00987 
00988 static ToolbarButtonProc * const _toolbar_button_procs[] = {
00989   ToolbarPauseClick,
00990   ToolbarFastForwardClick,
00991   ToolbarOptionsClick,
00992   ToolbarSaveClick,
00993   ToolbarMapClick,
00994   ToolbarTownClick,
00995   ToolbarSubsidiesClick,
00996   ToolbarStationsClick,
00997   ToolbarFinancesClick,
00998   ToolbarCompaniesClick,
00999   ToolbarGraphsClick,
01000   ToolbarLeagueClick,
01001   ToolbarIndustryClick,
01002   ToolbarTrainClick,
01003   ToolbarRoadClick,
01004   ToolbarShipClick,
01005   ToolbarAirClick,
01006   ToolbarZoomInClick,
01007   ToolbarZoomOutClick,
01008   ToolbarBuildRailClick,
01009   ToolbarBuildRoadClick,
01010   ToolbarBuildWaterClick,
01011   ToolbarBuildAirClick,
01012   ToolbarForestClick,
01013   ToolbarMusicClick,
01014   ToolbarNewspaperClick,
01015   ToolbarHelpClick,
01016   ToolbarSwitchClick,
01017 };
01018 
01019 struct MainToolbarWindow : Window {
01020   MainToolbarWindow(const WindowDesc *desc) : Window(desc)
01021   {
01022     this->SetWidgetDisabledState(TBN_PAUSE, _networking && !_network_server); // if not server, disable pause button
01023     this->SetWidgetDisabledState(TBN_FASTFORWARD, _networking); // if networking, disable fast-forward button
01024 
01025     CLRBITS(this->flags4, WF_WHITE_BORDER_MASK);
01026 
01027     this->FindWindowPlacementAndResize(desc);
01028     PositionMainToolbar(this);
01029     DoZoomInOutWindow(ZOOM_NONE, this);
01030   }
01031 
01032   virtual void OnPaint()
01033   {
01034     /* Draw brown-red toolbar bg. */
01035     GfxFillRect(0, 0, this->width - 1, this->height - 1, 0xB2);
01036     GfxFillRect(0, 0, this->width - 1, this->height - 1, 0xB4, FILLRECT_CHECKER);
01037 
01038     /* If spectator, disable all construction buttons
01039      * ie : Build road, rail, ships, airports and landscaping
01040      * Since enabled state is the default, just disable when needed */
01041     this->SetWidgetsDisabledState(_local_company == COMPANY_SPECTATOR, TBN_RAILS, TBN_ROADS, TBN_WATER, TBN_AIR, TBN_LANDSCAPE, WIDGET_LIST_END);
01042     /* disable company list drop downs, if there are no companies */
01043     this->SetWidgetsDisabledState(ActiveCompanyCount() == TBN_PAUSE, TBN_STATIONS, TBN_FINANCES, TBN_TRAINS, TBN_ROADVEHS, TBN_SHIPS, TBN_AIRCRAFTS, WIDGET_LIST_END);
01044 
01045     this->SetWidgetDisabledState(TBN_RAILS, !CanBuildVehicleInfrastructure(VEH_TRAIN));
01046     this->SetWidgetDisabledState(TBN_AIR, !CanBuildVehicleInfrastructure(VEH_AIRCRAFT));
01047 
01048     this->DrawWidgets();
01049   }
01050 
01051   virtual void OnClick(Point pt, int widget)
01052   {
01053     if (_game_mode != GM_MENU && !this->IsWidgetDisabled(widget)) _toolbar_button_procs[widget](this);
01054   }
01055 
01056   virtual void OnDropdownSelect(int widget, int index)
01057   {
01058     _menu_clicked_procs[widget](index);
01059   }
01060 
01061   virtual EventState OnKeyPress(uint16 key, uint16 keycode)
01062   {
01063     switch (keycode) {
01064       case WKC_F1: case WKC_PAUSE: ToolbarPauseClick(this); break;
01065       case WKC_F2: ShowGameOptions(); break;
01066       case WKC_F3: MenuClickSaveLoad(); break;
01067       case WKC_F4: ShowSmallMap(); break;
01068       case WKC_F5: ShowTownDirectory(); break;
01069       case WKC_F6: ShowSubsidiesList(); break;
01070       case WKC_F7: ShowCompanyStations(_local_company); break;
01071       case WKC_F8: ShowCompanyFinances(_local_company); break;
01072       case WKC_F9: ShowCompany(_local_company); break;
01073       case WKC_F10: ShowOperatingProfitGraph(); break;
01074       case WKC_F11: ShowCompanyLeagueTable(); break;
01075       case WKC_F12: ShowBuildIndustryWindow(); break;
01076       case WKC_SHIFT | WKC_F1: ShowVehicleListWindow(_local_company, VEH_TRAIN); break;
01077       case WKC_SHIFT | WKC_F2: ShowVehicleListWindow(_local_company, VEH_ROAD); break;
01078       case WKC_SHIFT | WKC_F3: ShowVehicleListWindow(_local_company, VEH_SHIP); break;
01079       case WKC_SHIFT | WKC_F4: ShowVehicleListWindow(_local_company, VEH_AIRCRAFT); break;
01080       case WKC_NUM_PLUS: // Fall through
01081       case WKC_EQUALS: // Fall through
01082       case WKC_SHIFT | WKC_EQUALS: // Fall through
01083       case WKC_SHIFT | WKC_F5: ToolbarZoomInClick(this); break;
01084       case WKC_NUM_MINUS: // Fall through
01085       case WKC_MINUS: // Fall through
01086       case WKC_SHIFT | WKC_MINUS: // Fall through
01087       case WKC_SHIFT | WKC_F6: ToolbarZoomOutClick(this); break;
01088       case WKC_SHIFT | WKC_F7: if (CanBuildVehicleInfrastructure(VEH_TRAIN)) ShowBuildRailToolbar(_last_built_railtype, -1); break;
01089       case WKC_SHIFT | WKC_F8: ShowBuildRoadToolbar(_last_built_roadtype); break;
01090       case WKC_SHIFT | WKC_F9: ShowBuildDocksToolbar(); break;
01091       case WKC_SHIFT | WKC_F10: if (CanBuildVehicleInfrastructure(VEH_AIRCRAFT)) ShowBuildAirToolbar(); break;
01092       case WKC_SHIFT | WKC_F11: ShowBuildTreesToolbar(); break;
01093       case WKC_SHIFT | WKC_F12: ShowMusicWindow(); break;
01094       case WKC_CTRL  | 'S': MenuClickSmallScreenshot(); break;
01095       case WKC_CTRL  | 'G': MenuClickWorldScreenshot(); break;
01096       case WKC_CTRL | WKC_ALT | 'C': if (!_networking) ShowCheatWindow(); break;
01097       case 'A': if (CanBuildVehicleInfrastructure(VEH_TRAIN)) ShowBuildRailToolbar(_last_built_railtype, 4); break; // Invoke Autorail
01098       case 'L': ShowTerraformToolbar(); break;
01099       case 'M': ShowSmallMap(); break;
01100       case 'V': ShowExtraViewPortWindow(); break;
01101       default: return ES_NOT_HANDLED;
01102     }
01103     return ES_HANDLED;
01104   }
01105 
01106   virtual void OnPlaceObject(Point pt, TileIndex tile)
01107   {
01108     _place_proc(tile);
01109   }
01110 
01111   virtual void OnTick()
01112   {
01113     if (this->IsWidgetLowered(TBN_PAUSE) != !!_pause_game) {
01114       this->ToggleWidgetLoweredState(TBN_PAUSE);
01115       this->InvalidateWidget(TBN_PAUSE);
01116     }
01117 
01118     if (this->IsWidgetLowered(TBN_FASTFORWARD) != !!_fast_forward) {
01119       this->ToggleWidgetLoweredState(TBN_FASTFORWARD);
01120       this->InvalidateWidget(TBN_FASTFORWARD);
01121     }
01122   }
01123 
01124   virtual void OnResize(Point new_size, Point delta)
01125   {
01126     if (this->width <= TBP_NORMAL_MAXBUTTON * TBP_BUTTONWIDTH) {
01127       SplitToolbar(this);
01128     } else {
01129       ResizeToolbar(this);
01130     }
01131   }
01132 
01133   virtual void OnTimeout()
01134   {
01135     for (uint i = TBN_SETTINGS; i < this->widget_count - 1; i++) {
01136       if (this->IsWidgetLowered(i)) {
01137         this->RaiseWidget(i);
01138         this->InvalidateWidget(i);
01139       }
01140     }
01141   }
01142 
01143   virtual void OnInvalidateData(int data)
01144   {
01145     if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, TBN_ZOOMIN, TBN_ZOOMOUT);
01146   }
01147 };
01148 
01149 static const Widget _toolb_normal_widgets[] = {
01150 {     WWT_IMGBTN,   RESIZE_LEFT,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_PAUSE,           STR_0171_PAUSE_GAME},               // TBN_PAUSE
01151 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_FASTFORWARD,     STR_FAST_FORWARD},                  // TBN_FASTFORWARD
01152 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_SETTINGS,        STR_0187_OPTIONS},                  // TBN_SETTINGS
01153 {   WWT_IMGBTN_2,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_SAVE,            STR_0172_SAVE_GAME_ABANDON_GAME},   // TBN_SAVEGAME
01154 
01155 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_SMALLMAP,        STR_0174_DISPLAY_MAP},              // TBN_SMALLMAP
01156 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_TOWN,            STR_0176_DISPLAY_TOWN_DIRECTORY},   // TBN_TOWNDIRECTORY
01157 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_SUBSIDIES,       STR_02DC_DISPLAY_SUBSIDIES},        // TBN_SUBSIDIES
01158 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_COMPANY_LIST,    STR_0173_DISPLAY_LIST_OF_COMPANY},  // TBN_STATIONS
01159 
01160 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_COMPANY_FINANCE, STR_0177_DISPLAY_COMPANY_FINANCES}, // TBN_FINANCES
01161 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_COMPANY_GENERAL, STR_0178_DISPLAY_COMPANY_GENERAL},  // TBN_COMPANIES
01162 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_GRAPHS,          STR_0179_DISPLAY_GRAPHS},           // TBN_GRAPHICS
01163 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_COMPANY_LEAGUE,  STR_017A_DISPLAY_COMPANY_LEAGUE},   // TBN_LEAGUE
01164 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_INDUSTRY,        STR_0312_FUND_CONSTRUCTION_OF_NEW}, // TBN_INDUSTRIES
01165 
01166 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_TRAINLIST,       STR_017B_DISPLAY_LIST_OF_COMPANY},  // TBN_TRAINS
01167 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_TRUCKLIST,       STR_017C_DISPLAY_LIST_OF_COMPANY},  // TBN_ROADVEHS
01168 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_SHIPLIST,        STR_017D_DISPLAY_LIST_OF_COMPANY},  // TBN_SHIPS
01169 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_AIRPLANESLIST,   STR_017E_DISPLAY_LIST_OF_COMPANY},  // TBN_AIRCRAFTS
01170 
01171 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_ZOOMIN,          STR_017F_ZOOM_THE_VIEW_IN},         // TBN_ZOOMIN
01172 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_ZOOMOUT,         STR_0180_ZOOM_THE_VIEW_OUT},        // TBN_ZOOMOUT
01173 
01174 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_BUILDRAIL,       STR_0181_BUILD_RAILROAD_TRACK},     // TBN_RAILS
01175 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_BUILDROAD,       STR_0182_BUILD_ROADS},              // TBN_ROADS
01176 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_BUILDWATER,      STR_0183_BUILD_SHIP_DOCKS},         // TBN_WATER
01177 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_BUILDAIR,        STR_0184_BUILD_AIRPORTS},           // TBN_AIR
01178 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_LANDSCAPING,     STR_LANDSCAPING_TOOLBAR_TIP},       // TBN_LANDSCAPE tree icon is SPR_IMG_PLANTTREES
01179 
01180 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_MUSIC,           STR_01D4_SHOW_SOUND_MUSIC_WINDOW},  // TBN_MUSICSOUND
01181 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_MESSAGES,        STR_0203_SHOW_LAST_MESSAGE_NEWS},   // TBN_NEWSREPORT
01182 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_IMG_QUERY,           STR_0186_LAND_BLOCK_INFORMATION},   // TBN_HELP
01183 {     WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,     0,     0,     0,    21, SPR_SWITCH_TOOLBAR,      STR_EMPTY},                         // TBN_SWITCHBAR
01184 {   WIDGETS_END},
01185 };
01186 
01187 static const WindowDesc _toolb_normal_desc(
01188   0, 0, 0, TBP_BUTTONHEIGHT, 640, TBP_BUTTONHEIGHT,
01189   WC_MAIN_TOOLBAR, WC_NONE,
01190   WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_NO_FOCUS,
01191   _toolb_normal_widgets
01192 );
01193 
01194 
01195 /* --- Toolbar handling for the scenario editor */
01196 
01197 static ToolbarButtonProc * const _scen_toolbar_button_procs[] = {
01198   ToolbarPauseClick,
01199   ToolbarFastForwardClick,
01200   ToolbarOptionsClick,
01201   ToolbarScenSaveOrLoad,
01202   ToolbarBtn_NULL,
01203   ToolbarBtn_NULL,
01204   ToolbarScenDateBackward,
01205   ToolbarScenDateForward,
01206   ToolbarScenMapTownDir,
01207   ToolbarZoomInClick,
01208   ToolbarZoomOutClick,
01209   ToolbarScenGenLand,
01210   ToolbarScenGenTown,
01211   ToolbarScenGenIndustry,
01212   ToolbarScenBuildRoad,
01213   ToolbarScenBuildDocks,
01214   ToolbarScenPlantTrees,
01215   ToolbarScenPlaceSign,
01216   NULL,
01217   NULL,
01218   NULL,
01219   NULL,
01220   NULL,
01221   NULL,
01222   ToolbarMusicClick,
01223   NULL,
01224   ToolbarHelpClick,
01225 };
01226 
01227 struct ScenarioEditorToolbarWindow : Window {
01228 public:
01229   ScenarioEditorToolbarWindow(const WindowDesc *desc) : Window(desc)
01230   {
01231     CLRBITS(this->flags4, WF_WHITE_BORDER_MASK);
01232 
01233     this->FindWindowPlacementAndResize(desc);
01234     PositionMainToolbar(this);
01235     DoZoomInOutWindow(ZOOM_NONE, this);
01236   }
01237 
01238   virtual void OnPaint()
01239   {
01240     this->SetWidgetDisabledState(TBSE_DATEBACKWARD, _settings_game.game_creation.starting_year <= MIN_YEAR);
01241     this->SetWidgetDisabledState(TBSE_DATEFORWARD, _settings_game.game_creation.starting_year >= MAX_YEAR);
01242 
01243     /* Draw brown-red toolbar bg. */
01244     GfxFillRect(0, 0, this->width - 1, this->height - 1, 0xB2);
01245     GfxFillRect(0, 0, this->width - 1, this->height - 1, 0xB4, FILLRECT_CHECKER);
01246 
01247     this->DrawWidgets();
01248 
01249     SetDParam(0, ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
01250     DrawStringCenteredTruncated(this->widget[TBSE_DATEBACKWARD].right, this->widget[TBSE_DATEFORWARD].left, 6, STR_00AF, TC_FROMSTRING);
01251 
01252     /* We hide this panel when the toolbar space gets too small */
01253     const Widget *panel = &this->widget[TBSE_SPACERPANEL];
01254     if (panel->left != panel->right) {
01255       DrawStringCenteredTruncated(panel->left + 1, panel->right - 1,  1, STR_0221_OPENTTD, TC_FROMSTRING);
01256       DrawStringCenteredTruncated(panel->left + 1, panel->right - 1, 11, STR_0222_SCENARIO_EDITOR, TC_FROMSTRING);
01257     }
01258   }
01259 
01260   virtual void OnClick(Point pt, int widget)
01261   {
01262     if (_game_mode == GM_MENU) return;
01263     _scen_toolbar_button_procs[widget](this);
01264   }
01265 
01266   virtual void OnDropdownSelect(int widget, int index)
01267   {
01268     /* The map button is in a different location on the scenario
01269      * editor toolbar, so we need to adjust for it. */
01270     if (widget == TBSE_SMALLMAP) widget = TBN_SMALLMAP;
01271     _menu_clicked_procs[widget](index);
01272     SndPlayFx(SND_15_BEEP);
01273   }
01274 
01275   virtual EventState OnKeyPress(uint16 key, uint16 keycode)
01276   {
01277     switch (keycode) {
01278       case WKC_F1: case WKC_PAUSE: ToolbarPauseClick(this); break;
01279       case WKC_F2: ShowGameOptions(); break;
01280       case WKC_F3: MenuClickSaveLoad(); break;
01281       case WKC_F4: ToolbarScenGenLand(this); break;
01282       case WKC_F5: ToolbarScenGenTown(this); break;
01283       case WKC_F6: ToolbarScenGenIndustry(this); break;
01284       case WKC_F7: ToolbarScenBuildRoad(this); break;
01285       case WKC_F8: ToolbarScenBuildDocks(this); break;
01286       case WKC_F9: ToolbarScenPlantTrees(this); break;
01287       case WKC_F10: ToolbarScenPlaceSign(this); break;
01288       case WKC_F11: ShowMusicWindow(); break;
01289       case WKC_F12: PlaceLandBlockInfo(); break;
01290       case WKC_CTRL | 'S': MenuClickSmallScreenshot(); break;
01291       case WKC_CTRL | 'G': MenuClickWorldScreenshot(); break;
01292 
01293       /* those following are all fall through */
01294       case WKC_NUM_PLUS:
01295       case WKC_EQUALS:
01296       case WKC_SHIFT | WKC_EQUALS:
01297       case WKC_SHIFT | WKC_F5: ToolbarZoomInClick(this); break;
01298 
01299       /* those following are all fall through */
01300       case WKC_NUM_MINUS:
01301       case WKC_MINUS:
01302       case WKC_SHIFT | WKC_MINUS:
01303       case WKC_SHIFT | WKC_F6: ToolbarZoomOutClick(this); break;
01304 
01305       case 'L': ShowEditorTerraformToolbar(); break;
01306       case 'M': ShowSmallMap(); break;
01307       case 'V': ShowExtraViewPortWindow(); break;
01308       default: return ES_NOT_HANDLED;
01309     }
01310     return ES_HANDLED;
01311   }
01312 
01313   virtual void OnPlaceObject(Point pt, TileIndex tile)
01314   {
01315     _place_proc(tile);
01316   }
01317 
01318   virtual void OnResize(Point new_size, Point delta)
01319   {
01320     /* There are 16 buttons plus some spacings if the space allows it.
01321      * Furthermore there are two panels of which one is non - essential
01322      * and that one can be removed if the space is too small. */
01323     uint buttons_width;
01324     uint spacing;
01325 
01326     static const int normal_min_width = (TBP_SCENARIO_MAXBUTTON * TBP_BUTTONWIDTH) + (2 * TBP_DATEPANELWIDTH);
01327     static const int one_less_panel_min_width = (TBP_SCENARIO_MAXBUTTON * TBP_BUTTONWIDTH) + TBP_DATEPANELWIDTH;
01328 
01329     if (this->width >= one_less_panel_min_width) {
01330       buttons_width = TBP_SCENARIO_MAXBUTTON * TBP_BUTTONWIDTH;
01331       spacing = this->width - ((this->width >= normal_min_width) ? normal_min_width : one_less_panel_min_width);
01332     } else {
01333       buttons_width = this->width - TBP_DATEPANELWIDTH;
01334       spacing = 0;
01335     }
01336     static const uint extra_spacing_at[] = { 3, 4, 7, 8, 10, 17, 0 };
01337 
01338     for (uint i = 0, x = 0, j = 0, b = 0; i < this->widget_count; i++) {
01339       switch (i) {
01340         case TBSE_SPACERPANEL:
01341           this->widget[i].left = x;
01342           if (this->width < normal_min_width) {
01343             this->widget[i].right = x;
01344             j++;
01345             continue;
01346           }
01347 
01348           x += TBP_DATEPANELWIDTH;
01349           this->widget[i].right = x - 1;
01350           break;
01351 
01352         case TBSE_DATEPANEL: {
01353           int offset = x - this->widget[i].left;
01354           this->widget[i + 1].left  += offset;
01355           this->widget[i + 1].right += offset;
01356           this->widget[i + 2].left  += offset;
01357           this->widget[i + 2].right += offset;
01358           this->widget[i].left = x;
01359           x += TBP_DATEPANELWIDTH;
01360           this->widget[i].right = x - 1;
01361           i += 2;
01362         } break;
01363 
01364         default:
01365           if (this->widget[i].bottom == 0) continue;
01366 
01367           this->widget[i].left = x;
01368           x += buttons_width / (TBP_SCENARIO_MAXBUTTON - b);
01369           this->widget[i].right = x - 1;
01370           buttons_width -= buttons_width / (TBP_SCENARIO_MAXBUTTON - b);
01371           b++;
01372           break;
01373       }
01374 
01375       if (extra_spacing_at[j] == i) {
01376         j++;
01377         uint add = spacing / (lengthof(extra_spacing_at) - j);
01378         spacing -= add;
01379         x += add;
01380       }
01381     }
01382   }
01383 
01384   virtual void OnTick()
01385   {
01386     if (this->IsWidgetLowered(TBSE_PAUSE) != !!_pause_game) {
01387       this->ToggleWidgetLoweredState(TBSE_PAUSE);
01388       this->SetDirty();
01389     }
01390 
01391     if (this->IsWidgetLowered(TBSE_FASTFORWARD) != !!_fast_forward) {
01392       this->ToggleWidgetLoweredState(TBSE_FASTFORWARD);
01393       this->SetDirty();
01394     }
01395   }
01396 
01397   virtual void OnInvalidateData(int data)
01398   {
01399     if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, TBSE_ZOOMIN, TBSE_ZOOMOUT);
01400   }
01401 };
01402 
01403 static const Widget _toolb_scen_widgets[] = {
01404 {  WWT_IMGBTN, RESIZE_LEFT,  COLOUR_GREY,   0,   0,  0, 21, SPR_IMG_PAUSE,       STR_0171_PAUSE_GAME},                  // TBSE_PAUSE
01405 {  WWT_IMGBTN, RESIZE_NONE,  COLOUR_GREY,   0,   0,  0, 21, SPR_IMG_FASTFORWARD, STR_FAST_FORWARD},                     // TBSE_FASTFORWARD
01406 {  WWT_IMGBTN, RESIZE_NONE,  COLOUR_GREY,   0,   0,  0, 21, SPR_IMG_SETTINGS,    STR_0187_OPTIONS},
01407 {WWT_IMGBTN_2, RESIZE_NONE,  COLOUR_GREY,   0,   0,  0, 21, SPR_IMG_SAVE,        STR_0297_SAVE_SCENARIO_LOAD_SCENARIO}, // TBSE_SAVESCENARIO
01408 
01409 {   WWT_PANEL, RESIZE_NONE,  COLOUR_GREY,   0,   0,  0, 21, 0x0,                 STR_NULL},                             // TBSE_SPACERPANEL
01410 
01411 {   WWT_PANEL, RESIZE_NONE,  COLOUR_GREY,   0, 129,  0, 21, 0x0,                 STR_NULL},                             // TBSE_DATEPANEL
01412 {  WWT_IMGBTN, RESIZE_NONE,  COLOUR_GREY,   3,  14,  5, 16, SPR_ARROW_DOWN,      STR_029E_MOVE_THE_STARTING_DATE},      // TBSE_DATEBACKWARD
01413 {  WWT_IMGBTN, RESIZE_NONE,  COLOUR_GREY, 113, 125,  5, 16, SPR_ARROW_UP,        STR_029F_MOVE_THE_STARTING_DATE},      // TBSE_DATEFORWARD
01414 
01415 {  WWT_IMGBTN, RESIZE_NONE,  COLOUR_GREY,   0,   0,  0, 21, SPR_IMG_SMALLMAP,    STR_0175_DISPLAY_MAP_TOWN_DIRECTORY},  // TBSE_SMALLMAP
01416 
01417 {  WWT_IMGBTN, RESIZE_NONE,  COLOUR_GREY,   0,   0,  0, 21, SPR_IMG_ZOOMIN,      STR_017F_ZOOM_THE_VIEW_IN},            // TBSE_ZOOMIN
01418 {  WWT_IMGBTN, RESIZE_NONE,  COLOUR_GREY,   0,   0,  0, 21, SPR_IMG_ZOOMOUT,     STR_0180_ZOOM_THE_VIEW_OUT},           // TBSE_ZOOMOUT
01419 
01420 {  WWT_IMGBTN, RESIZE_NONE,  COLOUR_GREY,   0,   0,  0, 21, SPR_IMG_LANDSCAPING, STR_022E_LANDSCAPE_GENERATION},        // TBSE_LANDGENERATE
01421 {  WWT_IMGBTN, RESIZE_NONE,  COLOUR_GREY,   0,   0,  0, 21, SPR_IMG_TOWN,        STR_022F_TOWN_GENERATION},             // TBSE_TOWNGENERATE
01422 {  WWT_IMGBTN, RESIZE_NONE,  COLOUR_GREY,   0,   0,  0, 21, SPR_IMG_INDUSTRY,    STR_0230_INDUSTRY_GENERATION},         // TBSE_INDUSTRYGENERATE
01423 {  WWT_IMGBTN, RESIZE_NONE,  COLOUR_GREY,   0,   0,  0, 21, SPR_IMG_BUILDROAD,   STR_0231_ROAD_CONSTRUCTION},           // TBSE_BUILDROAD
01424 {  WWT_IMGBTN, RESIZE_NONE,  COLOUR_GREY,   0,   0,  0, 21, SPR_IMG_BUILDWATER,  STR_0183_BUILD_SHIP_DOCKS},            // TBSE_BUILDDOCKS
01425 {  WWT_IMGBTN, RESIZE_NONE,  COLOUR_GREY,   0,   0,  0, 21, SPR_IMG_PLANTTREES,  STR_0288_PLANT_TREES},                 // TBSE_PLANTTREES
01426 {  WWT_IMGBTN, RESIZE_NONE,  COLOUR_GREY,   0,   0,  0, 21, SPR_IMG_SIGN,        STR_0289_PLACE_SIGN},                  // TBSE_PLACESIGNS
01427 
01428 {   WWT_EMPTY, RESIZE_NONE,  COLOUR_GREY,   0,   0,  0,  0, 0x0,                 STR_NULL},
01429 {   WWT_EMPTY, RESIZE_NONE,  COLOUR_GREY,   0,   0,  0,  0, 0x0,                 STR_NULL},
01430 {   WWT_EMPTY, RESIZE_NONE,  COLOUR_GREY,   0,   0,  0,  0, 0x0,                 STR_NULL},
01431 {   WWT_EMPTY, RESIZE_NONE,  COLOUR_GREY,   0,   0,  0,  0, 0x0,                 STR_NULL},
01432 {   WWT_EMPTY, RESIZE_NONE,  COLOUR_GREY,   0,   0,  0,  0, 0x0,                 STR_NULL},
01433 {   WWT_EMPTY, RESIZE_NONE,  COLOUR_GREY,   0,   0,  0,  0, 0x0,                 STR_NULL},
01434 {  WWT_IMGBTN, RESIZE_NONE,  COLOUR_GREY,   0,   0,  0, 21, SPR_IMG_MUSIC,       STR_01D4_SHOW_SOUND_MUSIC_WINDOW},
01435 {   WWT_EMPTY, RESIZE_NONE,  COLOUR_GREY,   0,   0,  0,  0, 0x0,                 STR_NULL},
01436 {  WWT_IMGBTN, RESIZE_NONE,  COLOUR_GREY,   0,   0,  0, 21, SPR_IMG_QUERY,       STR_0186_LAND_BLOCK_INFORMATION},
01437 {WIDGETS_END},
01438 };
01439 
01440 static const WindowDesc _toolb_scen_desc(
01441   0, 0, 130, TBP_BUTTONHEIGHT, 640, TBP_BUTTONHEIGHT,
01442   WC_MAIN_TOOLBAR, WC_NONE,
01443   WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_NO_FOCUS,
01444   _toolb_scen_widgets
01445 );
01446 
01447 /* --- Allocating the toolbar --- */
01448 
01449 void AllocateToolbar()
01450 {
01451   /* Clean old GUI values; railtype is (re)set by rail_gui.cpp */
01452   _last_built_roadtype = ROADTYPE_ROAD;
01453 
01454   if (_game_mode == GM_EDITOR) {
01455     new ScenarioEditorToolbarWindow(&_toolb_scen_desc);;
01456   } else {
01457     new MainToolbarWindow(&_toolb_normal_desc);
01458   }
01459 }

Generated on Mon Dec 14 21:00:04 2009 for OpenTTD by  doxygen 1.5.6