Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

cargodialog.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           cargodialog.cpp  -  description
00003                              -------------------
00004     begin                : Tue Oct 24 2000
00005     copyright            : (C) 2000 by Martin Bickel
00006     email                : bickel@asc-hq.org
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #include <pgimage.h>
00019 #include <pgtooltiphelp.h>
00020 #include "cargodialog.h"
00021 #include "cargowidget.h"
00022 #include "vehicletypeselector.h"
00023 
00024 #include "../containerbase.h"
00025 #include "../paradialog.h"
00026 #include "../messaginghub.h"
00027 #include "../iconrepository.h"
00028 #include "../vehicle.h"
00029 #include "../gamemap.h"
00030 #include "../containercontrols.h"
00031 
00032 #include "../asc-mainscreen.h"
00033 #include "../guiiconhandler.h"
00034 #include "../guifunctions.h"
00035 #include "../guifunctions-interface.h"
00036 #include "../unitctrl.h"
00037 #include "../cannedmessages.h"
00038 #include "../replay.h"
00039 #include "../dashboard.h"
00040 #include "../dialog.h"
00041 #include "../containerbase-functions.h"
00042 #include "../resourcenet.h"
00043 
00044 #include "../containerbase-functions.h"
00045 #include "../gameoptions.h"
00046 
00047 #include "selectionwindow.h"
00048 #include "ammotransferdialog.h"
00049 #include "unitinfodialog.h"
00050 
00051 // #include "cargowidget.cpp"
00052 
00053 const Vehicletype* selectVehicletype( ContainerBase* plant, const vector<Vehicletype*>& items );
00054 
00055 
00056 
00057 class CargoDialog;
00058 
00059 class SubWindow: public SigC::Object
00060 {
00061    protected:
00062       CargoDialog* cargoDialog;
00063       PG_Widget* widget;
00064       
00065       SubWindow() : cargoDialog(NULL), widget(NULL) {};
00066       ContainerBase* container(); 
00067    public:
00068       virtual bool available( CargoDialog* cd ) = 0;
00069       virtual ASCString getASCTXTname() = 0;
00070       virtual ASCString getFullName() = 0;
00071       virtual void registerSubwindow( CargoDialog* cd );
00072       virtual void registerChilds( CargoDialog* cd );
00073       virtual void update() = 0;
00074       virtual ~SubWindow() {} ;
00075 };
00076 
00077 
00078 class SubWinButton : public PG_Button
00079 {
00080    public:
00081       static const int buttonwidth = 47;
00082       static const int buttonheight = 28;
00083 
00084       SubWinButton( PG_Widget *parent, const SPoint& pos, SubWindow* subWindow ) : PG_Button( parent, PG_Rect( pos.x, pos.y, buttonwidth, buttonheight ), "", -1, "SubWinButton")
00085       {
00086          SetBackground( PRESSED, IconRepository::getIcon("cargo-buttonpressed.png").getBaseSurface() );
00087          SetBackground( HIGHLITED, IconRepository::getIcon("cargo-buttonhighlighted.png").getBaseSurface() );
00088          SetBackground( UNPRESSED, IconRepository::getIcon("cargo-buttonunpressed.png").getBaseSurface() );
00089          SetBorderSize(0,0,0);
00090          ASCString filename = ASCString("cargo-") + subWindow->getASCTXTname();
00091          SetIcon( IconRepository::getIcon( filename + ".png" ).getBaseSurface(), 
00092                   IconRepository::getIcon( filename + "-pressed.png" ).getBaseSurface(),
00093                   IconRepository::getIcon( filename + ".png" ).getBaseSurface() );
00094          SetToggle( true );
00095          new PG_ToolTipHelp ( this, subWindow->getFullName() );
00096       };
00097 };
00098 
00099 
00100 namespace CargoGuiFunctions {
00101    
00102    class MovementDestination : public GuiFunctions::Movement {
00103          PG_Widget& parent;
00104       public:
00105          MovementDestination( PG_Widget& masterParent ) : parent( masterParent)  {};
00106          
00107          void execute( const MapCoordinate& pos, ContainerBase* subject, int num )
00108          {
00109             GuiFunctions::Movement::execute( pos, subject, num );
00110             if ( !pendingVehicleActions.move )
00111                parent.QuitModal();
00112          }
00113    };
00114 
00115    class CancelMovement : public GuiFunctions::Cancel {
00116          PG_Widget& parent;
00117       public:
00118          CancelMovement ( PG_Widget& masterParent ) : parent( masterParent)  {};
00119          
00120          void execute( const MapCoordinate& pos, ContainerBase* subject, int num )
00121          {
00122             GuiFunctions::Cancel::execute( pos, subject, num );
00123             parent.QuitModal();
00124          }
00125    };
00126    
00127 
00128    class CloseDialog : public GuiFunction
00129    {
00130       CargoDialog& parent;
00131       public:
00132          CloseDialog( CargoDialog& masterParent ) : parent( masterParent)  {};
00133          bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00134          void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00135          bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00136          Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00137          ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00138    };
00139 
00140    
00141    class Movement : public GuiFunction
00142    {
00143          CargoDialog& parent;
00144       public:
00145          Movement( CargoDialog& masterParent ) : parent( masterParent)  {};
00146          bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00147          void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00148          bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00149          Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00150          ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00151    };
00152 
00153 
00154    class UnitProduction : public GuiFunction
00155    {
00156          CargoDialog& parent;
00157       public:
00158          UnitProduction( CargoDialog& masterParent ) : parent( masterParent)  {};
00159          bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00160          void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00161          bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00162          Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00163          ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00164    };
00165    
00166    class UnitTraining : public GuiFunction
00167    {
00168          CargoDialog& parent;
00169       public:
00170          UnitTraining( CargoDialog& masterParent ) : parent( masterParent)  {};
00171          bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00172          void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00173          bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00174          Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00175          ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00176    };
00177 
00178    class RefuelUnit : public GuiFunction
00179    {
00180          CargoDialog& parent;
00181       public:
00182          RefuelUnit( CargoDialog& masterParent ) : parent( masterParent)  {};
00183          bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00184          void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00185          bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00186          Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00187          ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00188    };
00189    
00190    class RefuelUnitDialog : public GuiFunction
00191    {
00192       CargoDialog& parent;
00193       public:
00194          RefuelUnitDialog( CargoDialog& masterParent ) : parent( masterParent)  {};
00195          bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00196          void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00197          bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00198          Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00199          ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00200    };
00201 
00202    class RepairUnit : public GuiFunction
00203    {
00204       CargoDialog& parent;
00205       public:
00206          RepairUnit( CargoDialog& masterParent ) : parent( masterParent)  {};
00207          bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00208          void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00209          bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00210          Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00211          ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00212    };
00213    
00214    class MoveUnitUp : public GuiFunction
00215    {
00216          CargoDialog& parent;
00217       public:
00218          MoveUnitUp ( CargoDialog& masterParent ) : parent( masterParent)  {};
00219          bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00220          void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00221          bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00222          Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00223          ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00224    };
00225    
00226    class MoveUnitIntoInnerContainer : public GuiFunction
00227    {
00228       CargoDialog& parent;
00229       public:
00230          MoveUnitIntoInnerContainer ( CargoDialog& masterParent ) : parent( masterParent)  {};
00231          bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00232          void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00233          bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00234          Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00235          ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00236    };
00237 
00238    
00239    class OpenContainer: public GuiFunction
00240    {
00241          CargoDialog& parent;
00242       public:
00243          OpenContainer( CargoDialog& masterParent ) : parent( masterParent)  {};
00244          bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00245          void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00246          bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00247          Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00248          ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00249    };
00250    
00251    class RecycleUnit : public GuiFunction
00252    {
00253       CargoDialog& parent;
00254       public:
00255          RecycleUnit( CargoDialog& masterParent ) : parent( masterParent)  {};
00256          bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00257          void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00258          bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00259          Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00260          ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00261    };
00262 
00263    class UnitInfo : public GuiFunction
00264    {
00265       CargoDialog& parent;
00266       public:
00267          UnitInfo( CargoDialog& masterParent ) : parent( masterParent)  {};
00268          bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00269          void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00270          bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00271          Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00272          ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00273    };
00274 
00275    class TransferUnitControl : public GuiFunction
00276    {
00277       CargoDialog& parent;
00278       public:
00279          TransferUnitControl( CargoDialog& masterParent ) : parent( masterParent)  {};
00280          bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00281          void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00282          Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00283          ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00284    };
00285 
00286    
00287    
00288 }; // namespace CargoGuiFunctions
00289 
00290 
00291 class BuildingControlWindow;
00292 class CargoInfoWindow;
00293 
00294 class CargoDialog : public Panel
00295 {
00296 
00297       ContainerControls containerControls;
00298    
00299       GuiIconHandler guiIconHandler;
00300       
00301       ContainerBase* container;
00302       bool setupOK;
00303       Surface infoImage;
00304 
00305       typedef vector<SubWindow*> Activesubwindows;
00306       Activesubwindows activesubwindows;
00307       
00308       typedef deallocating_vector<SubWindow*> Subwindows;
00309       Subwindows subwindows;
00310 
00311       vector<SubWinButton*> subWinButtons;
00312 
00313       CargoWidget* cargoWidget;
00314       SubWindow* researchWindow;
00315       SubWindow* matterWindow;
00316       BuildingControlWindow* buildingControlWindow;
00317 
00318       CargoInfoWindow* ciw;
00319       
00320       bool eventKeyDown(const SDL_KeyboardEvent* key)
00321       {
00322          if ( key->keysym.sym == SDLK_ESCAPE ) {
00323             QuitModal();
00324             return true;
00325          }
00326          return false;
00327       };
00328 
00329 
00330 
00331       void registerSpecialDisplay( const ASCString& name )
00332       {
00333          SpecialDisplayWidget* sdw = dynamic_cast<SpecialDisplayWidget*>( FindChild( name, true ) );
00334          if ( sdw )
00335             sdw->display.connect( SigC::slot( *this, &CargoDialog::painter ));
00336       };
00337 
00338       void registerSpecialInput( const ASCString& name )
00339       {
00340          SpecialInputWidget* siw = dynamic_cast<SpecialInputWidget*>( FindChild( name, true ) );
00341          if ( siw )
00342             siw->sigMouseButtonDown.connect( SigC::slot( *this, &CargoDialog::onClick ));
00343       };
00344 
00345       bool onClick ( PG_MessageObject* obj, const SDL_MouseButtonEvent* event )
00346       {
00347          PG_Widget* w = dynamic_cast<PG_Widget*>(obj);
00348          if ( w ) {
00349             // click( w->GetName() );
00350             return true;
00351          }
00352          return false;
00353       };
00354 
00355       void onUnitClick ( Vehicle* veh,SPoint pos, bool first )
00356       {
00357          // if ( veh )
00358          if ( mainScreenWidget&& mainScreenWidget->getGuiHost() && (!first || CGameOptions::Instance()->mouse.singleClickAction) ) { 
00359             SPoint iconPos = pos;
00360             if ( veh ) {
00361                iconPos.x -= smallGuiIconSizeX/2;
00362                iconPos.y -= smallGuiIconSizeY/2;
00363             } else {
00364                iconPos.x += 2;
00365                iconPos.y += 2;
00366             }
00367 
00368             mainScreenWidget->getGuiHost()->showSmallIcons( this, iconPos, false );
00369          }
00370             
00371       };
00372 
00373       void clearSmallIcons( )
00374       {
00375          if ( mainScreenWidget && mainScreenWidget->getGuiHost() )
00376             mainScreenWidget->getGuiHost()->clearSmallIcons();
00377       }
00378          
00379 
00380       
00381       void painter ( const PG_Rect &src, const ASCString& name, const PG_Rect &dst)
00382       {
00383          Surface screen = Surface::Wrap( PG_Application::GetScreen() );
00384 
00385          if ( name == "unitpad_unitsymbol" ) {
00386             Vehicle* v = dynamic_cast<Vehicle*>(container);
00387             if ( v ) 
00388                v->paint( screen, SPoint( dst.x, dst.y ));
00389          }
00390       };
00391 
00392       bool activate_i( int pane )
00393       {
00394          if ( pane >= 0 && pane < activesubwindows.size() ) {
00395             activate( activesubwindows[pane]->getASCTXTname() );
00396             activesubwindows[pane]->update();
00397          }
00398          return true;
00399       }
00400 
00401       void activate( const ASCString& pane )
00402       {
00403          BulkGraphicUpdates bgu( this );
00404          for ( int i = 0; i < activesubwindows.size(); ++i )
00405             if ( activesubwindows[i]->getASCTXTname() != pane )
00406                hide( activesubwindows[i]->getASCTXTname() );
00407 
00408          for ( int i = 0; i < activesubwindows.size(); ++i )
00409             if ( activesubwindows[i]->getASCTXTname() == pane )
00410                show( activesubwindows[i]->getASCTXTname() );
00411 
00412          for ( int i = 0; i< subWinButtons.size(); ++i )
00413             subWinButtons[i]->SetPressed( activesubwindows[i]->getASCTXTname() == pane );
00414       };
00415 
00416 
00417       void registerGuiFunctions( GuiIconHandler& handler )
00418       {
00419          registerCargoGuiFunctions( handler );
00420          handler.registerUserFunction( new CargoGuiFunctions::Movement( *this ) );
00421          handler.registerUserFunction( new CargoGuiFunctions::RefuelUnit( *this ) );
00422          handler.registerUserFunction( new CargoGuiFunctions::RefuelUnitDialog( *this ) );
00423          handler.registerUserFunction( new CargoGuiFunctions::RepairUnit( *this ) );
00424          handler.registerUserFunction( new CargoGuiFunctions::UnitProduction( *this ));
00425          handler.registerUserFunction( new CargoGuiFunctions::UnitTraining( *this ));
00426          handler.registerUserFunction( new CargoGuiFunctions::MoveUnitUp( *this ));
00427          handler.registerUserFunction( new CargoGuiFunctions::MoveUnitIntoInnerContainer( *this ));
00428          handler.registerUserFunction( new CargoGuiFunctions::OpenContainer( *this ));
00429          handler.registerUserFunction( new CargoGuiFunctions::RecycleUnit( *this ));
00430          handler.registerUserFunction( new CargoGuiFunctions::UnitInfo( *this ));
00431          handler.registerUserFunction( new CargoGuiFunctions::TransferUnitControl( *this ));
00432          handler.registerUserFunction( new CargoGuiFunctions::CloseDialog( *this ));
00433       }
00434 
00435       void checkStoringPosition( Vehicle* unit )
00436       {
00437          if ( mainScreenWidget&& mainScreenWidget->getGuiHost() ) {
00438             mainScreenWidget->getGuiHost()->eval( container->getPosition(), unit );
00439          }
00440          
00441          if ( mainScreenWidget && mainScreenWidget->getUnitInfoPanel() )
00442             mainScreenWidget->getUnitInfoPanel()->showUnitData( unit, NULL, NULL, true );
00443       }
00444 
00445       void updateLoadMeter()
00446       {
00447          if ( container->baseType->maxLoadableWeight > 0 ) 
00448             setBargraphValue ( "LoadingMeter", float( container->cargoWeight()) / container->baseType->maxLoadableWeight );
00449       }
00450       
00451       void dragUnitToInnerContainer( Vehicle* draggedUnit, Vehicle* targetUnit )
00452       {
00453          if ( !draggedUnit )
00454             return;
00455          
00456          if ( draggedUnit != targetUnit ) {
00457             if ( targetUnit ) {
00458                containerControls.moveUnitDown( draggedUnit, targetUnit );
00459             } else {
00460                if ( container->getCarrier() )
00461                   containerControls.moveUnitUp( draggedUnit );
00462                else {
00463                     
00464                }
00465             }
00466          }
00467          cargoChanged();
00468       }
00469       
00470       bool dragUnitToInnerContainerAvail( Vehicle* draggedUnit, Vehicle* targetUnit )
00471       {
00472          return containerControls.moveUnitDownAvail( draggedUnit, targetUnit );
00473       }
00474       
00475       void dragInProcess()
00476       {
00477          if ( mainScreenWidget && mainScreenWidget->getGuiHost() ) 
00478             mainScreenWidget->getGuiHost()->clearSmallIcons();
00479       }
00480       
00481       void dragAborted()
00482       {
00483          // to redraw everything
00484          cargoChanged();
00485       }
00486       
00487       
00488    public:
00489 
00490       CargoDialog (PG_Widget *parent, ContainerBase* cb );
00491 
00492       void addAvailableSubwin( SubWindow* w )
00493       {
00494          activesubwindows.push_back( w );
00495       };
00496 
00497       void updateResourceDisplay()
00498       {
00499          setLabelText( "energyavail", container->getResource(maxint, 0, true ) );
00500          setLabelText( "materialavail", container->getResource(maxint, 1, true ) );
00501          setLabelText( "fuelavail", container->getResource(maxint, 2, true ) );
00502          setLabelText( "numericaldamage", container->damage );
00503       }
00504 
00505 
00506       Vehicle* getMarkedUnit()
00507       {
00508          if ( cargoWidget )
00509             return cargoWidget->getMarkedUnit();
00510          else
00511             return NULL;
00512       }
00513       
00514       void cargoChanged()
00515       {
00516          //unitHighLight.setNew( unitHighLight.getMark() );
00517          if ( cargoWidget ) {
00518             cargoWidget->redrawAll();
00519             if ( mainScreenWidget && mainScreenWidget->getUnitInfoPanel() )
00520                mainScreenWidget->getUnitInfoPanel()->showUnitData( cargoWidget->getMarkedUnit(), NULL, NULL, true );
00521             
00522             checkStoringPosition( cargoWidget->getMarkedUnit() );
00523          }
00524          sigCargoChanged();
00525          updateResourceDisplay();
00526          showAmmo();
00527          updateLoadMeter();
00528       }
00529       
00530       int RunModal()
00531       {
00532          if ( setupOK )
00533             return Panel::RunModal();
00534          return 0;
00535       }
00536 
00537       bool ProcessEvent ( const SDL_Event *   event,bool   bModal = false  )
00538       {
00539          // the unit info panel must get the events first. If a unit is renamed and a character entered, this
00540          // key event shall go to the renaming - and not to the unit actions.
00541          if ( mainScreenWidget && mainScreenWidget->getUnitInfoPanel() ) 
00542             if ( mainScreenWidget->getUnitInfoPanel()->ProcessEvent( event, bModal ))
00543                return true;
00544 
00545          if ( mainScreenWidget && mainScreenWidget->getGuiHost() ) 
00546             if ( mainScreenWidget->getGuiHost()->ProcessEvent( event, bModal ))
00547                return true;
00548          
00549          if ( Panel::ProcessEvent( event, bModal )) 
00550             return true;
00551              
00552          return false;
00553       }
00554 
00555       void showAmmo()
00556       {
00557          setLabelText( "cmmun", container->getAmmo( cwcruisemissile, maxint, true ));
00558          setLabelText( "minemun", container->getAmmo( cwminen, maxint, true ));
00559          setLabelText( "bombmun", container->getAmmo( cwbombn, maxint, true ));
00560          setLabelText( "lmmun", container->getAmmo( cwlargemissilen, maxint, true ));
00561          setLabelText( "smmun", container->getAmmo( cwsmallmissilen, maxint, true ));
00562          setLabelText( "mgmun", container->getAmmo( cwmachinegunn, maxint, true ));
00563          setLabelText( "canmun", container->getAmmo( cwcannonn, maxint, true ));
00564          setLabelText( "torpmun", container->getAmmo( cwtorpedon, maxint, true ));
00565       }
00566 
00567       void userHandler( const ASCString& label, PropertyReadingContainer& pc, PG_Widget* parent, WidgetParameters widgetParams );
00568 
00569       ContainerBase* getContainer() { return container; };
00570 
00571       GameMap* getMap() { if ( container ) return container->getMap(); else return NULL; };
00572       
00573       ContainerControls& getControls() { return containerControls; };
00574 
00575       SigC::Signal0<void>  sigCargoChanged;
00576 
00577 
00578       ~CargoDialog()
00579       {
00580          if ( setupOK ) 
00581             NewGuiHost::popIconHandler();
00582 
00583       }
00584 
00585 };
00586 
00587 
00588 
00589 
00590 
00591 void cargoDialog( ContainerBase* cb )
00592 {
00593    CargoDialog cd ( NULL, cb );
00594    cd.Show();
00595    cd.RunModal();
00596 }
00597 
00598 
00599 
00600 
00601 
00602 class VehicleProduction_SelectionItemFactory: public VehicleTypeSelectionItemFactory  {
00603       bool fillResources;
00604       bool fillAmmo;
00605       const ContainerBase* plant;
00606 
00607       // is initialized by the constructor's call to filterVehicleTypes
00608       Container* produceables;
00609       
00610       Container& filterVehicleTypes( const Container& vehicles, const ContainerBase* productionplant )
00611       {
00612          produceables = new Container();
00613          for ( Container::const_iterator i = vehicles.begin(); i != vehicles.end(); ++i ) {
00614             if ( productionplant->getMap()->getgameparameter( cgp_produceOnlyResearchedStuffInternally )) {
00615                ContainerConstControls cc ( productionplant );
00616                if ( !(cc.unitProductionPrerequisites( *i ) & ~(1+2+4)))  // we are filtering out the bits for lack of resource
00617                   produceables->push_back( *i );
00618             } else
00619                produceables->push_back( *i );
00620          }
00621 
00622          return *produceables;
00623       }
00624 
00625    protected:
00626       void vehicleTypeSelected( const Vehicletype* type, bool mouse )
00627       {
00628          sigVehicleTypeSelected( type, mouse );
00629       }
00630 
00631       void itemMarked( const SelectionWidget* widget, bool mouse )
00632       {
00633          if ( !widget )
00634             return;
00635             
00636          const VehicleTypeBaseWidget* fw = dynamic_cast<const VehicleTypeBaseWidget*>(widget);
00637          assert( fw );
00638          sigVehicleTypeMarked( fw->getVehicletype() );
00639       }
00640 
00641       const Container& getOriginalItems() { 
00642          delete produceables;
00643          filterVehicleTypes( plant->getProduction(), plant );
00644          return *produceables; 
00645       };
00646 
00647    public:
00648       VehicleProduction_SelectionItemFactory( Resources plantResources, const ContainerBase* productionplant )
00649          : VehicleTypeSelectionItemFactory( plantResources, filterVehicleTypes( productionplant->getProduction(), productionplant), productionplant->getMap()->getCurrentPlayer() ), 
00650            fillResources(true), 
00651            fillAmmo(true), 
00652            plant(productionplant)
00653       {
00654       };
00655       
00656 
00657       bool getAmmoFilling()
00658       {
00659           if ( plant->baseType->hasFunction(ContainerBaseType::AmmoProduction))
00660              return fillAmmo;
00661           else
00662              return false;
00663       }
00664       
00665       bool setAmmoFilling( bool value )
00666       {
00667          fillAmmo = value;
00668          reloadAllItems();
00669          return true;
00670       }
00671       
00672       bool getResourceFilling()
00673       {
00674          return fillResources;
00675       }
00676       
00677       bool setResourceFilling( bool value )
00678       {
00679          fillResources = value;
00680          reloadAllItems();
00681          return true;
00682       }
00683 
00684      
00685       Resources getCost( const Vehicletype* type )
00686       {
00687          Resources cost = plant->getProductionCost( type );
00688          if ( fillResources )
00689             cost += Resources( 0, type->getStorageCapacity(plant->getMap()->_resourcemode).material, type->getStorageCapacity(plant->getMap()->_resourcemode).fuel );
00690 
00691          if ( fillAmmo )
00692             for ( int w = 0; w < type->weapons.count; ++w )
00693                if ( type->weapons.weapon[w].requiresAmmo() ) {
00694                   int wt = type->weapons.weapon[w].getScalarWeaponType();
00695                   cost += Resources( cwaffenproduktionskosten[wt][0], cwaffenproduktionskosten[wt][1], cwaffenproduktionskosten[wt][2] ) * type->weapons.weapon[w].count;
00696                }
00697          return cost;
00698       };
00699 
00700       SigC::Signal2<void,const Vehicletype*, bool > sigVehicleTypeSelected;
00701       SigC::Signal1<void,const Vehicletype* > sigVehicleTypeMarked;
00702       
00703       ~VehicleProduction_SelectionItemFactory()
00704       {
00705          delete produceables;  
00706       }
00707       
00708 };
00709 
00710 
00711 class AddProductionLine_SelectionItemFactory: public VehicleTypeSelectionItemFactory  {
00712       ContainerBase* plant;
00713    public:
00714       AddProductionLine_SelectionItemFactory( ContainerBase* my_plant, const Container& types ) : VehicleTypeSelectionItemFactory( my_plant->getResource(Resources(maxint,maxint,maxint), true), types, my_plant->getMap()->getCurrentPlayer() ), plant(my_plant)
00715       {
00716          
00717       };
00718       
00719       void vehicleTypeSelected( const Vehicletype* type, bool mouse )
00720       {
00721          ContainerControls cc( plant );
00722          int res = cc.buildProductionLine( type );
00723          if ( res < 0 )
00724             errorMessage( getmessage ( -res ));
00725       }
00726       
00727       Resources getCost( const Vehicletype* type )
00728       {
00729          ContainerControls cc ( plant );
00730          return cc.buildProductionLineResourcesNeeded( type );
00731       };
00732 };
00733 
00734 
00735 class VehicleProduction_SelectionWindow : public ASC_PG_Dialog {
00736       const Vehicletype* selected;
00737       const Vehicletype* finallySelected;
00738       ItemSelectorWidget* isw;
00739       VehicleProduction_SelectionItemFactory* factory;
00740       ContainerBase* my_plant;
00741    protected:
00742       void vtMarked( const Vehicletype* vt )
00743       {
00744          vtSelected( vt, true );
00745       }
00746 
00747       void vtSelected( const Vehicletype* vt, bool mouse )
00748       {
00749          selected = vt;
00750 
00751          if ( !mouse ) // enter pressed
00752             produce();
00753       };
00754 
00755       bool produce()
00756       {
00757          if ( selected ) {
00758             finallySelected = selected;
00759             quitModalLoop(0);
00760             return true;
00761          } else
00762             return false;
00763       }
00764 
00765 
00766       bool closeWindow()
00767       {
00768          selected = NULL;
00769          return ASC_PG_Dialog::closeWindow();
00770       }
00771       
00772       bool quitSignalled()
00773       {
00774          selected = NULL;
00775          QuitModal();
00776          return true;
00777       };
00778       
00779       void reLoadAndUpdate()
00780       {
00781          factory->setAvailableResource(my_plant->getResource(Resources(maxint,maxint,maxint)));
00782          isw->reLoad( true );
00783       }
00784 
00785       bool eventKeyDown(const SDL_KeyboardEvent* key)
00786       {
00787          int mod = SDL_GetModState() & ~(KMOD_NUM | KMOD_CAPS | KMOD_MODE);
00788          if ( mod )
00789             return false;
00790 
00791          if ( key->keysym.sym == SDLK_ESCAPE ) {
00792             closeWindow();
00793             return true;
00794          }
00795 
00796          return false;
00797       }
00798 
00799 
00800    public:
00801       VehicleProduction_SelectionWindow( PG_Widget *parent, const PG_Rect &r, ContainerBase* plant ) : ASC_PG_Dialog( parent, r, "Choose Vehicle Type" ), selected(NULL), finallySelected(NULL), isw(NULL), factory(NULL), my_plant( plant )
00802       {
00803          factory = new VehicleProduction_SelectionItemFactory( plant->getResource(Resources(maxint,maxint,maxint), true), plant );
00804 
00805          factory->setResourceFilling ( CGameOptions::Instance()->unitProduction.fillResources );
00806 
00807 
00808          factory->sigVehicleTypeSelected.connect ( SigC::slot( *this, &VehicleProduction_SelectionWindow::vtSelected ));
00809          factory->sigVehicleTypeMarked.connect ( SigC::slot( *this, &VehicleProduction_SelectionWindow::vtMarked ));
00810 
00811          isw = new ItemSelectorWidget( this, PG_Rect(10, GetTitlebarHeight(), r.Width() - 20, r.Height() - GetTitlebarHeight() - 40), factory );
00812          isw->sigQuitModal.connect( SigC::slot( *this, &VehicleProduction_SelectionWindow::quitSignalled));
00813 
00814          factory->reloadAllItems.connect( SigC::slot( *this, &VehicleProduction_SelectionWindow::reLoadAndUpdate ));
00815          
00816          
00817          int y = GetTitlebarHeight() + isw->Height();
00818          PG_CheckButton* fillRes = new PG_CheckButton( this, PG_Rect( 10, y + 2, r.Width() / 2 - 50, 20), "Fill with Resources" );
00819          
00820 
00821          if ( factory->getResourceFilling() ) 
00822             fillRes->SetPressed();
00823          fillRes->sigClick.connect( SigC::slot( *factory, &VehicleProduction_SelectionItemFactory::setResourceFilling ));
00824          
00825          if ( plant->baseType->hasFunction(ContainerBaseType::AmmoProduction)) {
00826             factory->setAmmoFilling( CGameOptions::Instance()->unitProduction.fillAmmo );
00827             PG_CheckButton* fillAmmo = new PG_CheckButton( this, PG_Rect( 10, y + 20, r.Width() / 2 - 50, 20), "Fill with Ammo" );
00828             if ( factory->getAmmoFilling() ) 
00829                fillAmmo->SetPressed();
00830             fillAmmo->sigClick.connect( SigC::slot( *factory, &VehicleProduction_SelectionItemFactory::setAmmoFilling ));
00831          } else
00832             factory->setAmmoFilling( false );
00833 
00834          PG_Rect rr ( r.Width() / 2 + 10, y + 2, (r.Width() - 20) - (r.Width() / 2 + 10) , 35);
00835          PG_Button* b  = new PG_Button( this, PG_Rect( rr.x + rr.h + 5, rr.y, rr.w - 40, rr.h ) , "Produce" );
00836          b->sigClick.connect( SigC::slot( *this,&VehicleProduction_SelectionWindow::produce ));
00837          
00838          if ( !plant->baseType->hasFunction(ContainerBaseType::NoProductionCustomization)) {
00839             PG_Button* b2 = new PG_Button( this, PG_Rect( rr.x, rr.y, rr.h, rr.h ), "+" );
00840             b2->sigClick.connect( SigC::slot( *this, &VehicleProduction_SelectionWindow::addProductionLine ));
00841             new PG_ToolTipHelp( b2, "Add production line");
00842    
00843             PG_Button* b3 = new PG_Button( this, PG_Rect( rr.x - rr.h - 5, rr.y, rr.h, rr.h ), "-" );
00844             b3->sigClick.connect( SigC::slot( *this, &VehicleProduction_SelectionWindow::removeProductionLine ));
00845             new PG_ToolTipHelp( b3, "Remove production line");
00846          }
00847 
00848          
00849          SetTransparency(0);
00850       };
00851 
00852       bool addProductionLine()
00853       {
00854          ContainerControls cc ( my_plant );
00855          {
00856             ItemSelectorWindow isw( NULL, PG_Rect( 100, 150, 400, 400 ),  "choose production line", new AddProductionLine_SelectionItemFactory( my_plant, cc.productionLinesBuyable() ));
00857             isw.Show();
00858             isw.RunModal();
00859          }
00860          reLoadAndUpdate();
00861          return true;
00862       }
00863 
00864       bool removeProductionLine()
00865       {
00866          if ( selected && choice_dlg("do you really want to remove this production line ?","~y~es","~n~o") == 1) {
00867             ContainerControls cc ( my_plant );
00868             cc.removeProductionLine( selected );
00869             reLoadAndUpdate();
00870          }
00871          return true;
00872       }
00873 
00874       
00875       bool fillWithAmmo()
00876       {
00877          return factory->getAmmoFilling();
00878       }
00879 
00880       bool fillWithResources()
00881       {
00882          return factory->getResourceFilling();
00883       }
00884       
00885 
00886       const Vehicletype* getVehicletype() { return finallySelected; };
00887 };
00888 
00889 
00890 /*
00891 const Vehicletype* selectVehicletype( ContainerBase* plant, const vector<Vehicletype*>& items )
00892 {
00893    VehicleTypeSelectionWindow fsw( NULL, PG_Rect( 10, 10, 400, 500 ), plant, items );
00894    fsw.Show();
00895    fsw.RunModal();
00896    const Vehicletype* v = fsw.getVehicletype();
00897    return v;
00898 }
00899 
00900 */
00901 
00902 
00903 void SubWindow::registerSubwindow( CargoDialog* cd )
00904 {
00905    cargoDialog = cd;
00906    cd->addAvailableSubwin( this );
00907 }
00908 
00909 void SubWindow::registerChilds( CargoDialog* cd )
00910 {
00911    widget = cd->FindChild( getASCTXTname(), true);
00912    if ( !widget )
00913       warning( "Could not find widget with name " + getASCTXTname() );
00914 }
00915 
00916 
00917 ContainerBase* SubWindow::container()
00918 {
00919    return cargoDialog->getContainer();
00920 }
00921 
00922 /*
00923 const int subWindowNum = 11;
00924 static const char* subWindowName[subWindowNum] =
00925 { "ammotransfer", "ammoproduction", "info", "cargoinfo", "conventionalpower", "mining", "netcontrol", "research", "resourceinfo", "solarpower", "windpower"
00926 };
00927 */
00928 
00929 
00930 
00931 class SolarPowerWindow : public SubWindow {
00932   
00933    public:
00934       bool available( CargoDialog* cd )
00935       {
00936          if ( !cd->getMap()->getCurrentPlayer().diplomacy.isAllied( cd->getContainer() ))
00937             return false;
00938          
00939          return cd->getContainer()->baseType->hasFunction( ContainerBaseType::SolarPowerPlant  );
00940       };
00941       
00942       ASCString getASCTXTname()
00943       {
00944          return "solarpower";
00945       };
00946 
00947       ASCString getFullName()
00948       {
00949          return "Solar Power Generation";
00950       };
00951       
00952       void update()
00953       {
00954          cargoDialog->setLabelText( "MaxPower", container()->maxplus.energy, widget );
00955       
00956          static const char* weathernames[] = {"terrain_weather_dry.png",
00957                                               "terrain_weather_lightrain.png",
00958                                               "terrain_weather_heavyrain.png",
00959                                               "terrain_weather_lightsnow.png",
00960                                               "terrain_weather_heavysnow.png",
00961                                               "terrain_weather_ice.png" };
00962 
00963 
00964          SolarPowerplant solarPowerPlant ( container() );
00965          Resources plus = solarPowerPlant.getPlus();
00966          cargoDialog->setLabelText( "CurrentPower", plus.energy, widget );
00967          cargoDialog->setImage( "Weather", weathernames[ container()->getMap()->getField( container()->getPosition() )->getweather() ], widget );
00968       }
00969 };
00970 
00971 class WindPowerWindow : public SubWindow {
00972    public:
00973       bool available( CargoDialog* cd )
00974       {
00975          if ( !cd->getMap()->getCurrentPlayer().diplomacy.isAllied( cd->getContainer() ))
00976             return false;
00977          
00978          return cd->getContainer()->baseType->hasFunction( ContainerBaseType::WindPowerPlant  );
00979       };
00980       
00981       ASCString getASCTXTname()
00982       {
00983          return "windpower";
00984       };
00985 
00986       ASCString getFullName()
00987       {
00988          return "Wind Power Generation";
00989       };
00990 
00991 
00992       void update()
00993       {
00994          cargoDialog->setLabelText( "MaxPower", container()->maxplus.energy, widget );
00995       
00996          WindPowerplant windPowerPlant ( container() );
00997          Resources plus = windPowerPlant.getPlus();
00998          cargoDialog->setLabelText( "CurrentPower", plus.energy, widget );
00999          
01000 #ifdef WEATHERGENERATOR
01001          if ( container()->getMap()->weatherSystem )
01002             cargoDialog->setLabelText( "Weather", container()->getMap()->weatherSystem->getCurrentWindSpeed(), widget );
01003 #else
01004          cargoDialog->setLabelText( "Weather", container()->getMap()->weather.windSpeed, widget );
01005 #endif
01006       }
01007 };
01008 
01009 class NetControlWindow : public SubWindow {
01010 
01011    private:
01012 
01013       bool click( PG_Button* b, int x, int y )
01014       {
01015          return true;
01016       }
01017 
01018       PG_Button* findButton( int x, int y )
01019       {
01020          char c = 'a' + x;
01021          ASCString buttonName = "Button" + ASCString::toString(y) + c;
01022          return dynamic_cast<PG_Button*>( widget->FindChild( buttonName, true ) );
01023       }
01024       
01025    public:
01026       bool available( CargoDialog* cd )
01027       {
01028          if ( !cd->getMap()->getCurrentPlayer().diplomacy.isAllied( cd->getContainer() ))
01029             return false;
01030          
01031          return dynamic_cast<Building*>(cd->getContainer()) != NULL;
01032       };
01033       
01034       ASCString getASCTXTname()
01035       {
01036          return "netcontrol";
01037       };
01038       
01039       ASCString getFullName()
01040       {
01041          return "Resource Network Control";
01042       };
01043 
01044 
01045       void registerChilds( CargoDialog* cd )
01046       {
01047          SubWindow::registerChilds( cd );
01048 
01049          if ( widget ) {
01050             for ( int x = 0; x < 3; ++x ) {
01051                for ( int y = 0; y < 4; ++y ) {
01052                   PG_Button* b = findButton( x, y );
01053                   if ( b ) {
01054                      b->sigClick.connect( SigC::bind( SigC::bind( SigC::slot( *this, &NetControlWindow::click ), x), y));
01055                      if( y >= 2)
01056                         b->