2
This file is part of Advanced Strategic Command; http://www.asc-hq.de
3
Copyright (C) 1994-1999 Martin Bickel and Marc Schellenberger
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.
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.
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
24
#include <pglistboxbaseitem.h>
25
#include <pgtooltiphelp.h>
27
#include "../iconrepository.h"
28
#include "../gamemap.h"
29
#include "../paradialog.h"
30
#include "playersetup.h"
31
#include "alliancesetup.h"
34
const int diplomaticStateIconSize = 20;
35
const int diplomaticStateIconSpace = 2;
38
template<typename SelectionType>
39
int getItemNum() { return 0; };
41
template<typename SelectionType>
42
const char* getStateName(int s) { return NULL; };
46
int getItemNum<DiplomaticStates>() { return diplomaticStateNum; };
49
const char* getStateName<DiplomaticStates>(int s) { return diplomaticStateNames[s]; };
53
int getItemNum<AllianceSetupWidget::DiplomaticTransitions>() { return diplomaticStateNum+1; };
56
const char* getStateName<AllianceSetupWidget::DiplomaticTransitions>(int s)
59
return "Sneak Attack";
61
return diplomaticStateNames[s-1];
65
ASCString getDiplomaticStateImage( DiplomaticStates s )
67
ASCString filename = "diplo-" + ASCString::toString(s) + ".png";
71
ASCString getDiplomaticStateImage( AllianceSetupWidget::DiplomaticTransitions s )
73
if ( s == AllianceSetupWidget::SNEAK_ATTACK ) {
74
ASCString filename = "diplo-sneak.png";
77
return getDiplomaticStateImage( DiplomaticStates( s-1 ));
81
template <typename SelectionType>
82
class ListBoxImageItem : public PG_ListBoxBaseItem {
85
ListBoxImageItem( PG_ListBox *parent, PG_Point pos, SelectionType s ) : PG_ListBoxBaseItem( parent, diplomaticStateIconSize + 2*diplomaticStateIconSpace ), state(s)
87
new PG_Image( this, PG_Point(diplomaticStateIconSpace,diplomaticStateIconSpace), IconRepository::getIcon( getDiplomaticStateImage(s)).getBaseSurface() , false );
88
new PG_Label( this, PG_Rect(diplomaticStateIconSize + 5, diplomaticStateIconSpace, 200,diplomaticStateIconSize), getStateName<SelectionType>(s));
91
SigC::Signal1<void,SelectionType> sigSet;
93
bool eventMouseButtonUp(const SDL_MouseButtonEvent* button)
95
if(button->button != 1) {
99
PG_ListBox* listbox = dynamic_cast<PG_ListBox*>(GetParent());
101
if(listbox == NULL || !listbox->IsVisible()) {
105
listbox->SelectItem(this);
106
listbox->QuitModal();
117
template <typename SelectionType>
118
class DiplomaticModeChooser : public PG_Widget {
126
PG_ListBox listBox( NULL, PG_Rect( x, y + Height(), 250, getItemNum<SelectionType>() * ( diplomaticStateIconSpace * 2 + diplomaticStateIconSize ) + 4 ));
127
for ( int i = 0; i < getItemNum<SelectionType>(); ++i) {
128
ListBoxImageItem<SelectionType>* item = new ListBoxImageItem<SelectionType>( NULL, PG_Point(0,0), SelectionType(i));
129
item->sigSet.connect( SigC::slot( *this, &DiplomaticModeChooser::SetState));
130
listBox.AddChild( item );
137
DiplomaticModeChooser ( PG_Widget *parent, const PG_Rect& pos, SelectionType& dm, bool writeable ) : PG_Widget( parent, pos, true ), mode(dm), writePossible( writeable )
141
SigC::Signal1<void,SelectionType> sigStateChange;
143
void eventDraw (SDL_Surface *surface, const PG_Rect &rect)
145
Surface s = Surface::Wrap( surface );
146
s.Blit( IconRepository::getIcon( getDiplomaticStateImage(mode) ) );
149
void SetState( SelectionType state )
154
sigStateChange(state);
157
bool eventMouseButtonUp(const SDL_MouseButtonEvent* button)
159
if (button->button != 1) {
170
AllianceSetupWidget::AllianceSetupWidget( GameMap* gamemap, bool allEditable, PG_Widget *parent, const PG_Rect &r, const std::string &style ) : PG_ScrollWidget( parent, r, style ) , actmap ( gamemap )
172
this->allEditable = allEditable;
175
for ( int i = 0; i < actmap->getPlayerCount(); ++i ) {
176
vector<DiplomaticTransitions> t;
177
vector< DiplomaticStates > s;
179
const DiplomaticStateVector& diplo = actmap->player[i].diplomacy;
181
for ( int j = 0; j < actmap->getPlayerCount(); ++j ) {
182
DiplomaticStateVector::QueuedStateChanges::const_iterator change = diplo.queuedStateChanges.find(j);
183
if ( change != diplo.queuedStateChanges.end() )
184
t.push_back( DiplomaticTransitions( change->second + 1 ));
186
t.push_back( DiplomaticTransitions( diplo.getState(j) + 1 ));
187
s.push_back( diplo.getState(j));
190
stateChanges.push_back ( t );
191
states.push_back ( s );
193
if ( actmap->player[i].exist() )
198
const int colWidth = 40;
199
const int lineHeight = 30;
200
const int barSpace = 5;
201
const int spacing = 10;
202
const int nameLength = 200;
203
const int barOverhang = 20;
204
const int sqaureWidth = lineHeight;
205
const int lineLength = sqaureWidth + nameLength + playerNum * (colWidth + spacing) + barOverhang;
206
const int colHeight = barOverhang + playerNum * (lineHeight + spacing) - spacing + barOverhang;
208
#define calcx(counter) (sqaureWidth + nameLength + spacing + counter * (colWidth + spacing) )
209
#define calcy(counter) (barOverhang + counter * (lineHeight + spacing))
212
for ( int i = 0; i < actmap->getPlayerCount(); ++i )
213
if ( actmap->player[i].exist() ) {
214
int x = calcx(counter);
216
ColoredBar* verticalBar = new ColoredBar( actmap->player[i].getColor(), this, PG_Rect( x, 0, colWidth, colHeight ));
217
verticalBar->SetTransparency( 128 );
224
for ( int i = 0; i < actmap->getPlayerCount(); ++i ) // rows
225
if ( actmap->player[i].exist() ) {
230
int y = calcy(counter);
232
ColoredBar* horizontalBar = new ColoredBar( actmap->player[i].getColor(), this, PG_Rect( 0, y, lineLength, lineHeight ));
233
horizontalBar->SetTransparency( 128 );
235
pw.name = new PG_LineEdit( horizontalBar, PG_Rect( sqaureWidth, barSpace, nameLength, lineHeight-2*barSpace ));
236
pw.name->SetText( actmap->player[i].getName());
237
pw.name->SetEditable( false );
239
new PG_ToolTipHelp( pw.name, "Position: " + ASCString::toString(i) );
241
PG_ThemeWidget* col = new PG_ThemeWidget( horizontalBar, PG_Rect( barSpace, barSpace, sqaureWidth - 2*barSpace, lineHeight - 2*barSpace ));
242
col->SetSimpleBackground(true);
243
col->SetBackgroundColor ( actmap->player[i].getColor());
244
col->SetBorderSize(0);
247
for ( int j = 0; j < actmap->getPlayerCount(); ++j ) // columns
248
if ( actmap->player[j].exist() ) {
250
int x = calcx(cnt2) - barSpace;
251
PG_Rect rect ( x + (colWidth - diplomaticStateIconSize)/2 , (lineHeight - diplomaticStateIconSize)/2,diplomaticStateIconSize,diplomaticStateIconSize);
253
DiplomaticModeChooser<DiplomaticStates>* dmc = new DiplomaticModeChooser<DiplomaticStates>( horizontalBar, rect, getState(i,j), true );
254
dmc->sigStateChange.connect( SigC::bind( SigC::slot( *this, &AllianceSetupWidget::setState ), j, i));
255
diplomaticWidgets[ linearize( i,j) ] = dmc;
257
DiplomaticTransitions& s = stateChanges[i][j];
258
DiplomaticModeChooser<DiplomaticTransitions>* dmc = new DiplomaticModeChooser<DiplomaticTransitions>( horizontalBar, rect, s, i == gamemap->actplayer );
259
// dmc->sigStateChange.connect( SigC::bind( SigC::slot( *this, &AllianceSetupWidget::setState ), j, i));
260
diplomaticWidgets[ linearize( i,j) ] = dmc;
267
playerWidgets.push_back( pw );
272
SetTransparency(255);
276
void AllianceSetupWidget::setState( DiplomaticStates s, int actingPlayer, int secondPlayer )
278
getState( actingPlayer, secondPlayer) = s;
280
DiplomaticWidgets::iterator i = diplomaticWidgets.find( linearize( actingPlayer, secondPlayer) );
281
if ( i != diplomaticWidgets.end() )
282
i->second->Redraw(true);
285
DiplomaticStates& AllianceSetupWidget::getState( int actingPlayer, int secondPlayer )
287
return states.at(actingPlayer).at(secondPlayer);
290
int AllianceSetupWidget::linearize( int actingPlayer, int secondPlayer )
292
return actingPlayer * actmap->getPlayerCount() + secondPlayer;
296
void AllianceSetupWidget::Apply()
298
for ( int acting = 0; acting < actmap->getPlayerCount(); ++acting )
299
for ( int second = 0; second < actmap->getPlayerCount(); ++second ) {
302
if ( getState( acting, second ) != actmap->player[acting].diplomacy.getState( second ))
303
actmap->player[acting].diplomacy.setState( second, getState( acting, second ));
305
if ( acting == actmap->actplayer ) {
306
if ( stateChanges[acting][second] == SNEAK_ATTACK ) {
307
actmap->player[acting].diplomacy.sneakAttack( second );
309
DiplomaticStates s = DiplomaticStates( stateChanges[acting][second] - 1);
311
DiplomaticStateVector::QueuedStateChanges::iterator q = actmap->player[acting].diplomacy.queuedStateChanges.find( second );
312
if ( q == actmap->player[acting].diplomacy.queuedStateChanges.end() )
313
t = getState( acting, second );
318
actmap->player[acting].diplomacy.propose( second, s );
326
AllianceSetupWidget::~AllianceSetupWidget()
339
class AllianceSetupWindow : public ASC_PG_Dialog {
340
AllianceSetupWidget* asw;
343
AllianceSetupWindow( GameMap* actmap, bool allEditable, PG_Widget *parent, const PG_Rect &r ) : ASC_PG_Dialog( parent, r, "Diplomacy" ), changed(false)
345
asw = new AllianceSetupWidget( actmap, allEditable, this, PG_Rect( 5, 30, r.Width() - 10, r.Height() - 60 ));
346
PG_Button* ok = new PG_Button( this, PG_Rect( Width() - 200, Height() - 30, 90, 20 ), "OK" );
347
ok->sigClick.connect( SigC::slot( *this, &AllianceSetupWindow::Apply ));
348
PG_Button* cancel = new PG_Button( this, PG_Rect( Width() - 100, Height() - 30, 90, 20 ), "Cancel" );
349
cancel->sigClick.connect( SigC::slot( *this, &AllianceSetupWindow::QuitModal ));
360
bool isSomethingChanged() { return changed; };
364
bool setupalliances( GameMap* actmap, bool supervisor )
366
AllianceSetupWindow asw ( actmap, supervisor, NULL, PG_Rect( 100, 100, 600, 500 ));
369
return asw.isSomethingChanged();