00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <sigc++/sigc++.h>
00022
00023 #include "ammotransferdialog.h"
00024
00025 #include "../containercontrols.h"
00026 #include "../gameoptions.h"
00027 #include "../actions/servicing.h"
00028 #include "../sg.h"
00029 #include "../actions/servicecommand.h"
00030 #include "../spfst-legacy.h"
00031
00032 class TransferWidget : public PG_Widget {
00033 private:
00034 Transferrable* trans;
00035 PG_Slider* slider;
00036
00037 bool updatePos( long a = 0 )
00038 {
00039 if ( slider )
00040 slider->SetPosition( trans->getAmount( trans->getDstContainer() ));
00041 return true;
00042 }
00043
00044 bool updateRange()
00045 {
00046 int min = trans->getMin( trans->getDstContainer(), false );
00047
00048 int max;
00049 if ( trans->getMax( trans->getDstContainer(), true ) * 3 < trans->getMax( trans->getDstContainer(), false ))
00050 max = trans->getMax( trans->getDstContainer(), true );
00051 else
00052 max = trans->getMax( trans->getDstContainer(), false );
00053
00054 if ( slider )
00055 slider->SetRange( min, max );
00056
00057 updatePos();
00058 return true;
00059 }
00060
00061
00062 public:
00063 TransferWidget ( PG_Widget* parent, const PG_Rect& pos, Transferrable* transferrable, TransferHandler& handler ) : PG_Widget( parent,pos ), trans( transferrable ), slider(NULL)
00064 {
00065 if ( transferrable->isExchangable() ) {
00066 slider = new PG_Slider( this, PG_Rect( 0, 25, pos.w, 15 ), PG_ScrollBar::HORIZONTAL );
00067
00068 updateRange();
00069
00070 slider->sigSlide.connect( SigC::slot( *transferrable, &Transferrable::setDestAmount ));
00071 slider->sigSlideEnd.connect( SigC::slot( *this, &TransferWidget::updatePos));
00072
00073 handler.updateRanges.connect( SigC::slot( *this, &TransferWidget::updateRange));
00074 }
00075
00076
00077 PG_Rect labels = PG_Rect( 0, 0, pos.w, 20 );
00078 PG_Label* l = new PG_Label ( this, labels, transferrable->getName() );
00079 l->SetAlignment( PG_Label::CENTER );
00080
00081 l = new PG_Label ( this, labels );
00082 l->SetAlignment( PG_Label::LEFT );
00083 transferrable->sigSourceAmount.connect( SigC::slot( *l, &PG_Label::SetText ));
00084
00085 l = new PG_Label ( this, labels );
00086 l->SetAlignment( PG_Label::RIGHT );
00087 transferrable->sigDestAmount.connect( SigC::slot( *l, &PG_Label::SetText ));
00088 };
00089 };
00090
00091
00092 class AmmoTransferWindow : public ASC_PG_Dialog {
00093 private:
00094 ContainerBase* first;
00095 ContainerBase* second;
00096 TransferHandler* handler;
00097
00098 ServiceCommand* command;
00099
00100 Surface img1,img2;
00101
00102 bool ok()
00103 {
00104 if( command ) {
00105 command->saveTransfers();
00106 command->execute( createContext( actmap ) );
00107 } else {
00108 errorMessage("Assertion failed: no command object");
00109 }
00110 QuitModal();
00111 return true;
00112 }
00113
00114 public:
00115 AmmoTransferWindow ( ContainerBase* source, ContainerBase* destination, PG_Widget* parent, ServiceCommand* command );
00116
00117 bool somethingToTransfer() { return handler->getTransfers().size(); };
00118
00119 bool eventKeyDown(const SDL_KeyboardEvent* key)
00120 {
00121 if ( key->keysym.sym == SDLK_ESCAPE ) {
00122 QuitModal();
00123 return true;
00124 }
00125 return false;
00126 }
00127
00128 ~AmmoTransferWindow()
00129 {
00130 if ( !command )
00131 delete handler;
00132 }
00133
00134 };
00135
00136
00137 AmmoTransferWindow :: AmmoTransferWindow ( ContainerBase* source, ContainerBase* destination, PG_Widget* parent, ServiceCommand* command )
00138 : ASC_PG_Dialog( NULL, PG_Rect( 30, 30, 400, 400 ), "Transfer" ),
00139 first (source), second( destination ), handler( NULL )
00140 {
00141
00142 this->command = command;
00143 if ( command ) {
00144 handler = & command->getTransferHandler();
00145 } else {
00146 handler = new TransferHandler( source, destination );
00147 }
00148
00149 int ypos = 30;
00150 int border = 10;
00151
00152
00153 img1 = source->getImage();
00154 img2 = destination->getImage();
00155
00156 const int singleTransferHeight = 60;
00157
00158 int expectedHeight = handler->getTransfers().size() * singleTransferHeight;
00159 if ( handler->ammoProductionPossible() )
00160 expectedHeight += 30;
00161
00162 int newHeight = min( PG_Application::GetScreen()->h - 60, expectedHeight + 130 );
00163 SizeWidget( w, newHeight );
00164
00165
00166 PG_ScrollWidget* area = new PG_ScrollWidget ( this, PG_Rect( border, ypos, w - border, h - 80 ));
00167 area->SetTransparency( 255 );
00168
00169 (new PG_ThemeWidget( area, PG_Rect( 5,3, fieldsizex, fieldsizey)))->SetBackground( img1.getBaseSurface(), PG_Draw::STRETCH );
00170 (new PG_ThemeWidget( area, PG_Rect( area->Width() - 5 - fieldsizex, 3, fieldsizex, fieldsizey)))->SetBackground( img2.getBaseSurface(), PG_Draw::STRETCH );
00171
00172
00173 ypos = fieldsizex + 5;
00174 if ( handler->ammoProductionPossible() ) {
00175 PG_CheckButton* production = new PG_CheckButton( area, PG_Rect( border, ypos, area->w - 30, 20 ), "allow ammo production" );
00176 if ( CGameOptions::Instance()->autoproduceammunition )
00177 production->SetPressed( );
00178 production->sigClick.connect( SigC::slot( *handler, &TransferHandler::allowAmmoProduction ));
00179 ypos += 30;
00180 }
00181
00182 for ( TransferHandler::Transfers::iterator i = handler->getTransfers().begin(); i != handler->getTransfers().end(); ++i ) {
00183 new TransferWidget( area, PG_Rect( 0, ypos, area->w - 30, 50 ), *i, *handler );
00184 ypos += singleTransferHeight;
00185 }
00186
00187 int buttonWidth = 150;
00188 PG_Button* b = new PG_Button( this, PG_Rect( w - buttonWidth - border, h - 30 - border, buttonWidth, 30), "OK" );
00189 b->sigClick.connect( SigC::slot( *this, &AmmoTransferWindow::ok ));
00190
00191 for ( TransferHandler::Transfers::iterator i = handler->getTransfers().begin(); i != handler->getTransfers().end(); ++i )
00192 (*i)->showAll();
00193 }
00194
00195 void ammoTransferWindow ( ContainerBase* source, ContainerBase* destination, ServiceCommand* command )
00196 {
00197 AmmoTransferWindow atw( source, destination, NULL, command );
00198 if ( atw.somethingToTransfer() ) {
00199 atw.Show();
00200 atw.RunModal();
00201 }
00202 }