1 // Copyright (C) 2007 Ole Laursen
2 // Copyright (C) 2007, 2008, 2009 Ben Asselstine
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.
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.
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
22 #include <sigc++/functors/mem_fun.h>
24 #include "stack-editor-dialog.h"
26 #include "glade-helpers.h"
27 #include "ucompose.hpp"
31 #include "armyproto.h"
33 #include "heroproto.h"
34 #include "GraphicsCache.h"
35 #include "playerlist.h"
36 #include "stacklist.h"
37 #include "hero-editor-dialog.h"
40 #include "select-army-dialog.h"
45 int const max_stack_size = 8;
48 StackEditorDialog::StackEditorDialog(Stack *s, int m)
49 : strength_column(_("Strength"), strength_renderer),
50 moves_column(_("Max Moves"), moves_renderer),
51 upkeep_column(_("Upkeep"), upkeep_renderer)
57 Glib::RefPtr<Gtk::Builder> xml
58 = Gtk::Builder::create_from_file(get_glade_path()
59 + "/stack-editor-dialog.ui");
61 xml->get_widget("dialog", dialog);
63 if (stack->getOwner())
65 // setup the player combo
66 player_combobox = manage(new Gtk::ComboBoxText);
68 int c = 0, player_no = 0;
69 for (Playerlist::iterator i = Playerlist::getInstance()->begin(),
70 end = Playerlist::getInstance()->end(); i != end; ++i, ++c)
73 player_combobox->append_text(player->getName());
74 if (player == stack->getOwner())
78 player_combobox->set_active(player_no);
79 player_combobox->signal_changed().connect
80 (sigc::mem_fun(*this, &StackEditorDialog::on_player_changed));
83 xml->get_widget("player_hbox", box);
84 box->pack_start(*player_combobox, Gtk::PACK_SHRINK);
87 // setup the army list
88 army_list = Gtk::ListStore::create(army_columns);
90 xml->get_widget("army_treeview", army_treeview);
91 army_treeview->set_model(army_list);
93 army_treeview->append_column("", army_columns.image);
95 strength_renderer.property_editable() = true;
96 strength_renderer.signal_edited()
97 .connect(sigc::mem_fun(*this, &StackEditorDialog::on_strength_edited));
98 strength_column.set_cell_data_func
100 sigc::mem_fun(*this, &StackEditorDialog::cell_data_strength));
101 army_treeview->append_column(strength_column);
103 moves_renderer.property_editable() = true;
104 moves_renderer.signal_edited()
105 .connect(sigc::mem_fun(*this, &StackEditorDialog::on_moves_edited));
106 moves_column.set_cell_data_func
108 sigc::mem_fun(*this, &StackEditorDialog::cell_data_moves));
109 army_treeview->append_column(moves_column);
111 upkeep_renderer.property_editable() = true;
112 upkeep_renderer.signal_edited()
113 .connect(sigc::mem_fun(*this, &StackEditorDialog::on_upkeep_edited));
114 upkeep_column.set_cell_data_func
116 sigc::mem_fun(*this, &StackEditorDialog::cell_data_upkeep));
117 army_treeview->append_column(upkeep_column);
119 army_treeview->append_column(_("Name"), army_columns.name);
121 xml->get_widget("fortified_checkbutton", fortified_checkbutton);
122 fortified_checkbutton->set_active(stack->getFortified());
123 fortified_checkbutton->signal_toggled().connect(
124 sigc::mem_fun(this, &StackEditorDialog::on_fortified_toggled));
126 xml->get_widget("add_button", add_button);
127 xml->get_widget("remove_button", remove_button);
128 xml->get_widget("copy_button", copy_button);
129 xml->get_widget("edit_hero_button", edit_hero_button);
131 add_button->signal_clicked().connect(
132 sigc::mem_fun(this, &StackEditorDialog::on_add_clicked));
133 remove_button->signal_clicked().connect(
134 sigc::mem_fun(this, &StackEditorDialog::on_remove_clicked));
135 copy_button->signal_clicked().connect(
136 sigc::mem_fun(this, &StackEditorDialog::on_copy_clicked));
137 edit_hero_button->signal_clicked().connect(
138 sigc::mem_fun(this, &StackEditorDialog::on_edit_hero_clicked));
140 army_treeview->get_selection()->signal_changed()
141 .connect(sigc::mem_fun(this, &StackEditorDialog::on_selection_changed));
143 for (Stack::iterator i = stack->begin(), end = stack->end(); i != end; ++i)
145 set_button_sensitivity();
148 StackEditorDialog::~StackEditorDialog()
152 void StackEditorDialog::set_parent_window(Gtk::Window &parent)
154 dialog->set_transient_for(parent);
155 //dialog->set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
158 int StackEditorDialog::run()
161 int response = dialog->run();
163 if (response == Gtk::RESPONSE_ACCEPT) // accepted
165 // remove removed armies from stack
166 for (Stack::iterator i = stack->begin(), end = stack->end(); i != end;)
172 for (Gtk::TreeIter j = army_list->children().begin(),
173 jend = army_list->children().end(); j != jend; ++j)
174 if ((*j)[army_columns.army] == a)
187 //set the stats for all of the armies in our list
188 for (Gtk::TreeIter j = army_list->children().begin(),
189 jend = army_list->children().end(); j != jend; ++j)
191 Army *a = (*j)[army_columns.army];
192 a->setStat(Army::STRENGTH, (*j)[army_columns.strength]);
193 a->setStat(Army::MOVES, (*j)[army_columns.moves]);
194 a->setUpkeep((*j)[army_columns.upkeep]);
196 bool ship = stack->hasShip();
197 // add added armies to stack
198 for (Gtk::TreeIter j = army_list->children().begin(),
199 jend = army_list->children().end(); j != jend; ++j)
201 Army *a = (*j)[army_columns.army];
204 if (std::find(stack->begin(), stack->end(), a) == stack->end())
208 // now set allegiance, it's important to do it after possibly new stack
209 // armies have been added
212 Player *player = get_selected_player();
214 Player *old_active = Playerlist::getActiveplayer();
215 Playerlist::getInstance()->setActiveplayer(player);
216 Stack *new_stack = new Stack(*stack);
217 GameMap::getInstance()->removeStack(stack);
219 stack->setPlayer(player);
220 GameMap::getInstance()->putStack(stack);
221 Playerlist::getInstance()->setActiveplayer(old_active);
227 Player *StackEditorDialog::get_selected_player()
229 int c = 0, row = player_combobox->get_active_row_number();
230 Player *player = Playerlist::getInstance()->getNeutral();
231 for (Playerlist::iterator i = Playerlist::getInstance()->begin(),
232 end = Playerlist::getInstance()->end(); i != end; ++i, ++c)
241 void StackEditorDialog::on_copy_clicked()
243 Gtk::TreeIter i = army_treeview->get_selection()->get_selected();
246 Player *player = get_selected_player();
247 Army *army = (*i)[army_columns.army];
248 add_army(new Army(*army, player));
251 set_button_sensitivity();
253 void StackEditorDialog::on_add_clicked()
255 SelectArmyDialog d(stack->getOwner(), true);
256 d.set_parent_window(*dialog);
259 Player *player = get_selected_player();
260 const ArmyProto *army = d.get_selected_army();
263 if (army->isHero() == true)
265 HeroProto *hp = new HeroProto(*army);
266 hp->setOwnerId(player->getId());
267 add_army(new Hero(*hp));
271 add_army(new Army(*army, player));
276 void StackEditorDialog::on_edit_hero_clicked()
278 Gtk::TreeIter i = army_treeview->get_selection()->get_selected();
281 Army *army = (*i)[army_columns.army];
282 Hero *hero = dynamic_cast<Hero*>(army);
283 HeroEditorDialog d(hero);
285 (*i)[army_columns.name] = hero->getName();
289 void StackEditorDialog::on_remove_clicked()
291 Gtk::TreeIter i = army_treeview->get_selection()->get_selected();
294 Army *army = (*i)[army_columns.army];
296 if (std::find(stack->begin(), stack->end(), army) == stack->end())
300 set_button_sensitivity();
303 void StackEditorDialog::add_army(Army *a)
305 GraphicsCache *gc = GraphicsCache::getInstance();
306 Gtk::TreeIter i = army_list->append();
307 (*i)[army_columns.army] = a;
308 (*i)[army_columns.image] = gc->getArmyPic(a->getOwner()->getArmyset(),
309 a->getTypeId(), a->getOwner(),
311 (*i)[army_columns.strength] = a->getStat(Army::STRENGTH, false);
312 (*i)[army_columns.moves] = a->getStat(Army::MOVES, false);
313 (*i)[army_columns.upkeep] = a->getUpkeep();
314 (*i)[army_columns.name] = a->getName();
316 army_treeview->get_selection()->select(i);
318 set_button_sensitivity();
321 void StackEditorDialog::on_selection_changed()
323 set_button_sensitivity();
326 void StackEditorDialog::set_button_sensitivity()
328 Gtk::TreeIter i = army_treeview->get_selection()->get_selected();
329 int armies = army_list->children().size();
330 add_button->set_sensitive(armies < max_stack_size);
331 copy_button->set_sensitive(armies < max_stack_size);
332 remove_button->set_sensitive(armies > min_size && i);
335 Army *army = (*i)[army_columns.army];
338 edit_hero_button->set_sensitive(true);
339 copy_button->set_sensitive(false);
342 edit_hero_button->set_sensitive(false);
344 Player *player = get_selected_player();
345 if (player == Playerlist::getInstance()->getNeutral())
346 fortified_checkbutton->set_sensitive(false);
348 fortified_checkbutton->set_sensitive(true);
351 void StackEditorDialog::on_fortified_toggled()
353 stack->setFortified(fortified_checkbutton->get_active());
356 void StackEditorDialog::on_player_changed()
358 GraphicsCache *gc = GraphicsCache::getInstance();
359 Player *player = get_selected_player();
360 if (player == Playerlist::getInstance()->getNeutral())
361 fortified_checkbutton->set_active(false);
362 set_button_sensitivity();
364 for (Gtk::TreeIter j = army_list->children().begin(),
365 jend = army_list->children().end(); j != jend; ++j)
367 Army *a = (*j)[army_columns.army];
368 (*j)[army_columns.image] = gc->getArmyPic(player->getArmyset(),
370 player, NULL)->to_pixbuf();
373 void StackEditorDialog::cell_data_strength(Gtk::CellRenderer *renderer,
374 const Gtk::TreeIter& i)
376 dynamic_cast<Gtk::CellRendererSpin*>(renderer)->property_adjustment()
377 = new Gtk::Adjustment((*i)[army_columns.strength],
378 MIN_STRENGTH_FOR_ARMY_UNITS,
379 MAX_STRENGTH_FOR_ARMY_UNITS, 1);
380 dynamic_cast<Gtk::CellRendererSpin*>(renderer)->property_text() =
381 String::ucompose("%1", (*i)[army_columns.strength]);
384 void StackEditorDialog::on_strength_edited(const Glib::ustring &path,
385 const Glib::ustring &new_text)
387 int str = atoi(new_text.c_str());
388 if (str < (int)MIN_STRENGTH_FOR_ARMY_UNITS || str >
389 (int)MAX_STRENGTH_FOR_ARMY_UNITS)
391 (*army_list->get_iter(Gtk::TreePath(path)))[army_columns.strength] = str;
394 void StackEditorDialog::cell_data_moves(Gtk::CellRenderer *renderer,
395 const Gtk::TreeIter& i)
397 dynamic_cast<Gtk::CellRendererSpin*>(renderer)->property_adjustment()
398 = new Gtk::Adjustment((*i)[army_columns.moves],
399 MIN_MOVES_FOR_ARMY_UNITS,
400 MAX_MOVES_FOR_ARMY_UNITS, 1);
401 dynamic_cast<Gtk::CellRendererSpin*>(renderer)->property_text() =
402 String::ucompose("%1", (*i)[army_columns.moves]);
405 void StackEditorDialog::on_moves_edited(const Glib::ustring &path,
406 const Glib::ustring &new_text)
408 int moves = atoi(new_text.c_str());
409 if (moves < (int)MIN_MOVES_FOR_ARMY_UNITS || moves >
410 (int)MAX_MOVES_FOR_ARMY_UNITS)
412 (*army_list->get_iter(Gtk::TreePath(path)))[army_columns.moves] = moves;
415 void StackEditorDialog::cell_data_upkeep(Gtk::CellRenderer *renderer,
416 const Gtk::TreeIter& i)
418 dynamic_cast<Gtk::CellRendererSpin*>(renderer)->property_adjustment()
419 = new Gtk::Adjustment((*i)[army_columns.upkeep],
420 MIN_UPKEEP_FOR_ARMY_UNITS,
421 MAX_UPKEEP_FOR_ARMY_UNITS, 1);
422 dynamic_cast<Gtk::CellRendererSpin*>(renderer)->property_text() =
423 String::ucompose("%1", (*i)[army_columns.upkeep]);
426 void StackEditorDialog::on_upkeep_edited(const Glib::ustring &path,
427 const Glib::ustring &new_text)
429 int upkeep = atoi(new_text.c_str());
430 if (upkeep < (int)MIN_UPKEEP_FOR_ARMY_UNITS ||
431 upkeep > (int)MAX_UPKEEP_FOR_ARMY_UNITS)
433 (*army_list->get_iter(Gtk::TreePath(path)))[army_columns.upkeep] = upkeep;