initial commit, lordsawar source, slightly modified
[lordsawar] / src / editor / players-dialog.cpp
1 //  Copyright (C) 2007 Ole Laursen
2 //  Copyright (C) 2007, 2008, 2009 Ben Asselstine
3 //
4 //  This program is free software; you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation; either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU Library General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program; if not, write to the Free Software
16 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
17 //  02110-1301, USA.
18
19 #include <config.h>
20
21 #include <assert.h>
22 #include <gtkmm.h>
23 #include <sigc++/functors/mem_fun.h>
24
25 #include "players-dialog.h"
26
27 #include "glade-helpers.h"
28 #include "defs.h"
29 #include "File.h"
30 #include "player.h"
31 #include "playerlist.h"
32 #include "armysetlist.h"
33 #include "stacklist.h"
34 #include "citylist.h"
35 #include "player.h"
36 #include "ucompose.hpp"
37 #include "game-parameters.h"
38 #include "CreateScenarioRandomize.h"
39
40
41 namespace
42 {
43     Glib::ustring player_type_to_string(guint32 type)
44     {
45         switch (type)
46         {
47         case Player::HUMAN: return HUMAN_PLAYER_TYPE;
48         case Player::AI_FAST: return EASY_PLAYER_TYPE;
49         case Player::AI_SMART: return HARD_PLAYER_TYPE;
50         default: return NO_PLAYER_TYPE;
51         }
52     }
53 }
54
55 PlayersDialog::PlayersDialog(CreateScenarioRandomize *random, int width, int height)
56   : type_column(_("Type"), type_renderer),
57     gold_column(_("Gold"), gold_renderer),
58     name_column(_("Name"), name_renderer)
59 {
60   d_width = width;
61   d_height = height;
62   Glib::RefPtr<Gtk::Builder> xml
63     = Gtk::Builder::create_from_file(get_glade_path() + "/players-dialog.ui");
64
65   xml->get_widget("dialog", dialog);
66
67   // setup the player settings
68   player_list = Gtk::ListStore::create(player_columns);
69
70   xml->get_widget("player_treeview", player_treeview);
71   player_treeview->set_model(player_list);
72
73   // the type column
74   player_type_list = Gtk::ListStore::create(player_type_columns);
75   Gtk::TreeModel::iterator i;
76   i = player_type_list->append();
77   (*i)[player_type_columns.type] = HUMAN_PLAYER_TYPE;
78   i = player_type_list->append();
79   (*i)[player_type_columns.type] = EASY_PLAYER_TYPE;
80   i = player_type_list->append();
81   (*i)[player_type_columns.type] = HARD_PLAYER_TYPE;
82   i = player_type_list->append();
83   (*i)[player_type_columns.type] = NO_PLAYER_TYPE;
84
85   type_renderer.property_model() = player_type_list;
86   type_renderer.property_text_column() = 0;
87   type_renderer.property_has_entry() = false;
88   type_renderer.property_editable() = true;
89
90   type_renderer.signal_edited()
91     .connect(sigc::mem_fun(*this, &PlayersDialog::on_type_edited));
92   type_column.set_cell_data_func
93     ( type_renderer, sigc::mem_fun(*this, &PlayersDialog::cell_data_type));
94   player_treeview->append_column(type_column);
95
96   // name column
97   name_renderer.property_editable() = true;
98   name_renderer.signal_edited().connect
99     (sigc::mem_fun(*this, &PlayersDialog::on_name_edited));
100   name_column.set_cell_data_func
101     (name_renderer, sigc::mem_fun(*this, &PlayersDialog::cell_data_name));
102   player_treeview->append_column(name_column);
103
104   // gold column
105   gold_renderer.property_editable() = true;
106   gold_renderer.signal_edited().connect
107     (sigc::mem_fun(*this, &PlayersDialog::on_gold_edited));
108   gold_column.set_cell_data_func
109     (gold_renderer, sigc::mem_fun(*this, &PlayersDialog::cell_data_gold));
110   player_treeview->append_column(gold_column);
111
112   // add default players
113   default_player_names.push_back(random->getPlayerName(Shield::WHITE));
114   default_player_names.push_back(random->getPlayerName(Shield::GREEN));
115   default_player_names.push_back(random->getPlayerName(Shield::YELLOW));
116   default_player_names.push_back(random->getPlayerName(Shield::LIGHT_BLUE));
117   default_player_names.push_back(random->getPlayerName(Shield::ORANGE));
118   default_player_names.push_back(random->getPlayerName(Shield::DARK_BLUE));
119   default_player_names.push_back(random->getPlayerName(Shield::RED));
120   default_player_names.push_back(random->getPlayerName(Shield::BLACK));
121
122   Playerlist *pl = Playerlist::getInstance();
123
124   // merge defined players with predefined
125   std::vector<Player *> players_to_add(default_player_names.size(), 0);
126   for (Playerlist::iterator i = pl->begin(), end = pl->end(); i != end; ++i)
127     {
128       Player *player = *i;
129       if (player == pl->getNeutral())
130         continue;
131       players_to_add[player->getId()] = player;
132     }
133
134   player_name_seq::iterator current_name = default_player_names.begin();
135   for (unsigned int j = 0; j < players_to_add.size(); ++j)
136     if (players_to_add[j])
137       {
138         Player *player = players_to_add[j];
139         add_player(player_type_to_string(player->getType()),
140                    player->getName(), player->getGold(), player);
141         ++current_name;
142       }
143     else
144       {
145         int gold = 0;
146         random->getBaseGold(100, &gold);
147         gold = random->adjustBaseGold(gold);
148         add_player(NO_PLAYER_TYPE, *current_name, gold, 0);
149         ++current_name;
150       }
151 }
152
153 PlayersDialog::~PlayersDialog()
154 {
155   delete dialog;
156 }
157
158 void PlayersDialog::set_parent_window(Gtk::Window &parent)
159 {
160   dialog->set_transient_for(parent);
161 }
162
163 int PlayersDialog::run()
164 {
165   dialog->show_all();
166   int response = dialog->run();
167   Playerlist *pl = Playerlist::getInstance();
168
169   if (response == Gtk::RESPONSE_ACCEPT) // accepted
170     {
171
172       // update the player list
173       int c = 0;
174       for (Gtk::TreeIter i = player_list->children().begin(),
175            end = player_list->children().end(); i != end; ++i, ++c)
176         {
177           Glib::ustring type = (*i)[player_columns.type];
178           Glib::ustring name = (*i)[player_columns.name];
179           int gold = (*i)[player_columns.gold];
180
181           GameParameters::Player player;
182           player.name = name;
183           if (type == HUMAN_PLAYER_TYPE)
184             player.type = GameParameters::Player::HUMAN;
185           else if (type == EASY_PLAYER_TYPE)
186             player.type = GameParameters::Player::EASY;
187           else if (type == HARD_PLAYER_TYPE)
188             player.type = GameParameters::Player::HARD;
189           else if (type == NO_PLAYER_TYPE)
190             player.type = GameParameters::Player::OFF;
191           player.id = c;
192           pl->syncPlayer(player);
193           Player *p = pl->getPlayer(player.id);
194           (*i)[player_columns.player] = p;
195           if (p)
196             p->setGold(gold);
197         }
198     }
199
200   return response;
201 }
202
203 void PlayersDialog::cell_data_type(Gtk::CellRenderer *renderer,
204                                    const Gtk::TreeIter& i)
205 {
206   dynamic_cast<Gtk::CellRendererText*>(renderer)->property_text()
207     = (*i)[player_columns.type];
208 }
209
210 void PlayersDialog::on_type_edited(const Glib::ustring &path,
211                                    const Glib::ustring &new_text)
212 {
213   (*player_list->get_iter(Gtk::TreePath(path)))[player_columns.type]
214     = new_text;
215 }
216
217 void PlayersDialog::add_player(const Glib::ustring &type,
218                                const Glib::ustring &name, int gold,
219                                Player *player)
220 {
221   Gtk::TreeIter i = player_list->append();
222   (*i)[player_columns.type] = type;
223   (*i)[player_columns.name] = name;
224   (*i)[player_columns.gold] = gold;
225   (*i)[player_columns.player] = player;
226
227   player_treeview->get_selection()->select(i);
228 }
229
230 void PlayersDialog::cell_data_gold(Gtk::CellRenderer *renderer,
231                                   const Gtk::TreeIter& i)
232 {
233     dynamic_cast<Gtk::CellRendererSpin*>(renderer)->property_adjustment()
234           = new Gtk::Adjustment((*i)[player_columns.gold], 0, 10000, 1);
235     dynamic_cast<Gtk::CellRendererSpin*>(renderer)->property_text() = 
236       String::ucompose("%1", (*i)[player_columns.gold]);
237 }
238
239 void PlayersDialog::on_gold_edited(const Glib::ustring &path,
240                                    const Glib::ustring &new_text)
241 {
242   int gold = atoi(new_text.c_str());
243   (*player_list->get_iter(Gtk::TreePath(path)))[player_columns.gold] = gold;
244 }
245
246 void PlayersDialog::cell_data_name(Gtk::CellRenderer *renderer,
247                                   const Gtk::TreeIter& i)
248 {
249     dynamic_cast<Gtk::CellRendererText*>(renderer)->property_text() = 
250       String::ucompose("%1", (*i)[player_columns.name]);
251 }
252
253 void PlayersDialog::on_name_edited(const Glib::ustring &path,
254                                    const Glib::ustring &new_text)
255 {
256   (*player_list->get_iter(Gtk::TreePath(path)))[player_columns.name] = new_text;
257 }