Advanced Strategic Command
ammotransferdialog.cpp
Go to the documentation of this file.
1 /*
2  This file is part of Advanced Strategic Command; http://www.asc-hq.de
3  Copyright (C) 1994-2010 Martin Bickel and Marc Schellenberger
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; see the file COPYING. If not, write to the
17  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  Boston, MA 02111-1307 USA
19 */
20 
21 #include <sigc++/sigc++.h>
22 
23 #include "ammotransferdialog.h"
24 
25 #include "../containercontrols.h"
26 #include "../gameoptions.h"
27 #include "../actions/servicing.h"
28 #include "../sg.h"
29 #include "../actions/servicecommand.h"
30 #include "../spfst-legacy.h"
31 
32 class TransferWidget : public PG_Widget {
33  private:
34  Transferrable* trans;
35  PG_Slider* slider;
36 
37  bool updatePos( long a = 0 )
38  {
39  if ( slider )
40  slider->SetPosition( trans->getAmount( trans->getDstContainer() ));
41  return true;
42  }
43 
44  bool updateRange()
45  {
46  int min = trans->getMin( trans->getDstContainer(), false );
47 
48  int max;
49  if ( trans->getMax( trans->getDstContainer(), true ) * 3 < trans->getMax( trans->getDstContainer(), false ))
50  max = trans->getMax( trans->getDstContainer(), true );
51  else
52  max = trans->getMax( trans->getDstContainer(), false );
53 
54  if ( slider )
55  slider->SetRange( min, max );
56 
57  updatePos();
58  return true;
59  }
60 
61 
62  public:
63  TransferWidget ( PG_Widget* parent, const PG_Rect& pos, Transferrable* transferrable, TransferHandler& handler ) : PG_Widget( parent,pos ), trans( transferrable ), slider(NULL)
64  {
65  if ( transferrable->isExchangable() ) {
66  slider = new PG_Slider( this, PG_Rect( 0, 25, pos.w, 15 ), PG_ScrollBar::HORIZONTAL );
67 
68  updateRange();
69 
70  slider->sigSlide.connect( sigc::mem_fun( *transferrable, &Transferrable::setDestAmount ));
71  slider->sigSlideEnd.connect( sigc::mem_fun( *this, &TransferWidget::updatePos));
72 
73  handler.updateRanges.connect( sigc::mem_fun( *this, &TransferWidget::updateRange));
74  }
75 
76 
77  PG_Rect labels = PG_Rect( 0, 0, pos.w, 20 );
78  PG_Label* l = new PG_Label ( this, labels, transferrable->getName() );
79  l->SetAlignment( PG_Label::CENTER );
80 
81  l = new PG_Label ( this, labels );
82  l->SetAlignment( PG_Label::LEFT );
83  transferrable->sigSourceAmount.connect( sigc::mem_fun( *l, &PG_Label::SetText ));
84 
85  l = new PG_Label ( this, labels );
86  l->SetAlignment( PG_Label::RIGHT );
87  transferrable->sigDestAmount.connect( sigc::mem_fun( *l, &PG_Label::SetText ));
88  };
89 };
90 
91 
93  private:
94  ContainerBase* first;
95  ContainerBase* second;
96  TransferHandler* handler;
97 
98  ServiceCommand* command;
99 
100  Surface img1,img2;
101 
102  bool ok()
103  {
104  if( command ) {
105  command->saveTransfers();
106  command->execute( createContext( actmap ) );
107  } else {
108  errorMessage("Assertion failed: no command object");
109  }
110  QuitModal();
111  return true;
112  }
113 
114  public:
115  AmmoTransferWindow ( ContainerBase* source, ContainerBase* destination, PG_Widget* parent, ServiceCommand* command );
116 
117  bool somethingToTransfer() { return handler->getTransfers().size(); };
118 
119  bool eventKeyDown(const SDL_KeyboardEvent* key)
120  {
121  if ( key->keysym.sym == SDLK_ESCAPE ) {
122  QuitModal();
123  return true;
124  }
125  return false;
126  }
127 
129  {
130  if ( !command )
131  delete handler;
132  }
133 
134 };
135 
136 
137 AmmoTransferWindow :: AmmoTransferWindow ( ContainerBase* source, ContainerBase* destination, PG_Widget* parent, ServiceCommand* command )
138  : ASC_PG_Dialog( NULL, PG_Rect( 30, 30, 400, 400 ), "Transfer" ),
139  first (source), second( destination ), handler( NULL )
140 {
141 
142  this->command = command;
143  if ( command ) {
144  handler = & command->getTransferHandler();
145  } else {
146  handler = new TransferHandler( source, destination );
147  }
148 
149  int ypos = 30;
150  int border = 10;
151 
152 
153  img1 = source->getImage();
154  img2 = destination->getImage();
155 
156  const int singleTransferHeight = 60;
157 
158  int expectedHeight = handler->getTransfers().size() * singleTransferHeight;
159  if ( handler->ammoProductionPossible() )
160  expectedHeight += 30;
161 
162  int newHeight = min( PG_Application::GetScreen()->h - 60, expectedHeight + 130 );
163  SizeWidget( w, newHeight );
164 
165 
166  PG_ScrollWidget* area = new PG_ScrollWidget ( this, PG_Rect( border, ypos, w - border, h - 80 ));
167  area->SetTransparency( 255 );
168 
169  (new PG_ThemeWidget( area, PG_Rect( 5,3, fieldsizex, fieldsizey)))->SetBackground( img1.getBaseSurface(), PG_Draw::STRETCH );
170  (new PG_ThemeWidget( area, PG_Rect( area->Width() - 5 - fieldsizex, 3, fieldsizex, fieldsizey)))->SetBackground( img2.getBaseSurface(), PG_Draw::STRETCH );
171 
172 
173  ypos = fieldsizex + 5;
174  if ( handler->ammoProductionPossible() ) {
175  PG_CheckButton* production = new PG_CheckButton( area, PG_Rect( border, ypos, area->w - 30, 20 ), "allow ammo production" );
176  if ( CGameOptions::Instance()->autoproduceammunition )
177  production->SetPressed( );
178  production->sigClick.connect( sigc::mem_fun( *handler, &TransferHandler::allowAmmoProduction ));
179  ypos += 30;
180  }
181 
182  for ( TransferHandler::Transfers::iterator i = handler->getTransfers().begin(); i != handler->getTransfers().end(); ++i ) {
183  new TransferWidget( area, PG_Rect( 0, ypos, area->w - 30, 50 ), *i, *handler );
184  ypos += singleTransferHeight;
185  }
186 
187  int buttonWidth = 150;
188  PG_Button* b = new PG_Button( this, PG_Rect( w - buttonWidth - border, h - 30 - border, buttonWidth, 30), "OK" );
189  b->sigClick.connect( sigc::hide( sigc::mem_fun( *this, &AmmoTransferWindow::ok )));
190 
191  for ( TransferHandler::Transfers::iterator i = handler->getTransfers().begin(); i != handler->getTransfers().end(); ++i )
192  (*i)->showAll();
193 }
194 
195 void ammoTransferWindow ( ContainerBase* source, ContainerBase* destination, ServiceCommand* command )
196 {
197  AmmoTransferWindow atw( source, destination, NULL, command );
198  if ( atw.somethingToTransfer() ) {
199  atw.Show();
200  atw.RunModal();
201  }
202 }
bool ammoProductionPossible()
Definition: servicing.cpp:835
virtual Surface getImage() const =0
returns an image for the Container.
virtual ASCString getName()=0
void ammoTransferWindow(ContainerBase *source, ContainerBase *destination, ServiceCommand *command)
Context createContext(GameMap *gamemap)
virtual int getAmount(const ContainerBase *target)=0
SDL_Surface * getBaseSurface()
Definition: surface.h:116
#define fieldsizey
Definition: typen.h:441
sigc::signal< void, const std::string & > sigSourceAmount
Definition: servicing.h:83
ActionResult execute(const Context &context)
Definition: action.cpp:41
bool eventKeyDown(const SDL_KeyboardEvent *key)
Adapter class for using Paragui Dialogs in ASC. This class transfers the event control from ASC to Pa...
Definition: paradialog.h:127
virtual int getMin(ContainerBase *c, bool avail)=0
ContainerBase * getDstContainer()
Definition: servicing.cpp:176
TransferWidget(PG_Widget *parent, const PG_Rect &pos, Transferrable *transferrable, TransferHandler &handler)
#define fieldsizex
Definition: typen.h:440
void errorMessage(const ASCString &string)
static CGameOptions * Instance()
returns the only Instance
Definition: gameoptions.cpp:38
TransferHandler & getTransferHandler()
each call to getTransferHandler will deallocate the previous handler and create a new one Make sure t...
sigc::signal< bool > updateRanges
Definition: servicing.h:185
GameMap * actmap
Definition: spfst.cpp:64
The parent class of Vehicle and Building; The name Container originates from Battle Isle...
Definition: containerbase.h:40
const T & max(const T &a, const T &b, const T &c)
Definition: misc.h:97
const T & min(const T &a, const T &b, const T &c)
Definition: misc.h:80
AmmoTransferWindow(ContainerBase *source, ContainerBase *destination, PG_Widget *parent, ServiceCommand *command)
Transfers & getTransfers()
Definition: servicing.cpp:840
sigc::signal< void, const std::string & > sigDestAmount
Definition: servicing.h:84
bool setDestAmount(long amount)
Definition: servicing.cpp:181
virtual int getMax(ContainerBase *c, bool avail)=0
get maximum amount for that unit.
bool allowAmmoProduction(bool allow)
Definition: servicing.cpp:816
virtual bool isExchangable() const =0