1 // Copyright (C) 2008, 2009 Ben Asselstine
3 // This program is free software; you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation; either version 3 of the License, or
6 // (at your option) any later version.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU Library General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 #include <sigc++/functors/mem_fun.h>
22 #include "stack-info-dialog.h"
25 #include "glade-helpers.h"
26 #include "input-helpers.h"
27 #include "image-helpers.h"
28 #include "ucompose.hpp"
32 #include "armysetlist.h"
33 #include "playerlist.h"
35 #include "GraphicsCache.h"
38 #include "stacktile.h"
41 StackInfoDialog::StackInfoDialog(Vector<int> pos)
45 currently_selected_stack = NULL;
47 Glib::RefPtr<Gtk::Builder> xml
48 = Gtk::Builder::create_from_file(get_glade_path()
49 + "/stack-info-dialog.ui");
51 xml->get_widget("dialog", dialog);
53 window_closed.connect(sigc::mem_fun(dialog, &Gtk::Dialog::hide));
55 xml->get_widget("stack_table", stack_table);
58 xml->get_widget("group_button", group_button);
59 group_button->signal_clicked().connect
60 (sigc::mem_fun(*this, &StackInfoDialog::on_group_clicked));
61 xml->get_widget("ungroup_button", ungroup_button);
62 ungroup_button->signal_clicked().connect
63 (sigc::mem_fun(*this, &StackInfoDialog::on_ungroup_clicked));
67 StackInfoDialog::~StackInfoDialog()
69 if (army_info_tip != NULL)
73 void StackInfoDialog::set_parent_window(Gtk::Window &parent)
75 dialog->set_transient_for(parent);
76 //dialog->set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
79 void StackInfoDialog::hide()
84 void StackInfoDialog::run()
86 static int width = -1;
87 static int height = -1;
89 if (width != -1 && height != -1)
90 dialog->set_default_size(width, height);
95 dialog->get_size(width, height);
99 void StackInfoDialog::addStack(Stack *s, guint32 &idx)
101 s->sortForViewing(true);
102 Stack *target = new Stack(Playerlist::getInstance()->getNeutral(), s->getPos());
103 ArmyProto *baseproto = ArmyProto::createScout();
104 Army *army = new Army(*baseproto);
107 Fight fight(s, target, Fight::FOR_KICKS);
111 for (Stack::iterator it = s->begin(); it != s->end(); it++)
113 guint32 str = fight.getModifiedStrengthBonus(*it);
114 addArmy(first, s, *it, str, idx);
121 void StackInfoDialog::addArmy (bool first, Stack *s, Army *h, guint32 modified_strength, int idx)
123 GraphicsCache *gc = GraphicsCache::getInstance();
124 Player *player = h->getOwner();
127 bool greyed_out = s->getId() != currently_selected_stack->getId();
128 Gtk::ToggleButton *toggle = manage(new Gtk::ToggleButton);
129 Glib::RefPtr<Gdk::Pixbuf> pixbuf=
130 gc->getArmyPic(player->getArmyset(), h->getTypeId(), player, NULL,
131 greyed_out)->to_pixbuf();
133 Gtk::Image *image = NULL;
134 guint32 move_bonus = h->getStat(Army::MOVE_BONUS);
135 bool ship = h->getStat(Army::SHIP);
136 if (ship || move_bonus == (Tile::GRASS | Tile::WATER | Tile::FOREST |
137 Tile::HILLS | Tile::SWAMP | Tile::MOUNTAIN))
139 image = new Gtk::Image();
140 image->property_pixbuf() = gc->getMoveBonusPic(move_bonus, ship)->to_pixbuf();
144 toggle->set_active(s->getId() == currently_selected_stack->getId());
145 toggle->signal_toggled().connect
146 (sigc::bind(sigc::mem_fun(this,
147 &StackInfoDialog::on_army_toggled), toggle, s, h));
148 toggle->add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
149 toggles.push_back(toggle);
150 toggle->signal_button_press_event().connect
151 (sigc::bind(sigc::mem_fun(*this, &StackInfoDialog::on_army_button_event),
153 toggle->signal_button_release_event().connect
154 (sigc::bind(sigc::mem_fun(*this, &StackInfoDialog::on_army_button_event),
156 Gtk::Image *army_image = new Gtk::Image();
157 army_image->property_pixbuf() = pixbuf;
158 toggle->add(*manage(army_image));
160 Gtk::Label *name = new Gtk::Label(h->getName());
161 Glib::ustring str = "";
163 unsigned int strength_value = h->getStat(Army::STRENGTH);
164 str = String::ucompose("%1", strength_value);
165 if (modified_strength != strength_value)
166 str += String::ucompose(" (%1)", modified_strength);
168 Gtk::Label *strength = new Gtk::Label(str);
170 Gtk::Label *bonus = new Gtk::Label(h->getArmyBonusDescription());
171 Gtk::Label *moves = new Gtk::Label(String::ucompose("%1", h->getMoves()));
175 Gtk::RadioButton *radio;
176 if (radios.size() > 0)
178 Gtk::RadioButtonGroup b;
179 b = radios.front()->get_group();
180 radio = new Gtk::RadioButton(b);
183 radio = new Gtk::RadioButton();
184 radios.push_back(radio);
185 radio->set_active(s->getId() == currently_selected_stack->getId());
186 radio->signal_toggled().connect
187 (sigc::bind(sigc::mem_fun(this, &StackInfoDialog::on_stack_toggled),
189 stack_table->attach(*manage(radio), 0, 1, idx, idx + 1,
190 Gtk::SHRINK, Gtk::SHRINK);
193 stack_table->attach(*manage(toggle), 1, 2, idx, idx + 1,
194 Gtk::SHRINK, Gtk::SHRINK);
195 stack_table->attach(*manage(name), 2, 3, idx, idx + 1,
196 Gtk::SHRINK, Gtk::SHRINK);
197 stack_table->attach(*manage(strength), 3, 4, idx, idx+1,
198 Gtk::SHRINK, Gtk::SHRINK);
199 stack_table->attach(*manage(moves), 4, 5, idx, idx+1,
200 Gtk::SHRINK, Gtk::SHRINK);
202 stack_table->attach(*manage(image), 5, 6, idx, idx+1,
203 Gtk::SHRINK, Gtk::SHRINK);
204 stack_table->attach(*manage(bonus), 6, 7, idx, idx + 1,
205 Gtk::SHRINK, Gtk::SHRINK);
209 void StackInfoDialog::on_group_clicked()
211 StackTile *stile = GameMap::getStacks(tile);
212 Stack *stack = stile->group(Playerlist::getActiveplayer());
213 currently_selected_stack = stack;
214 stack->sortForViewing(true);
218 void StackInfoDialog::on_ungroup_clicked()
220 StackTile *stile = GameMap::getStacks(tile);
221 stile->ungroup(Playerlist::getActiveplayer());
225 void StackInfoDialog::fill_stack_info()
227 StackTile *stile = GameMap::getStacks(tile);
233 stack_table->foreach(sigc::mem_fun(stack_table, &Gtk::Container::remove));
234 stack_table->resize(6, MAX_ARMIES_ON_A_SINGLE_TILE);
236 Gtk::Label *str = new Gtk::Label(_("Str"));
237 stack_table->attach(*manage(str), 3, 4, 0, 1, Gtk::SHRINK, Gtk::SHRINK);
239 Gtk::Label *moves = new Gtk::Label(_("Move"));
240 stack_table->attach(*manage(moves), 4, 5, 0, 1, Gtk::SHRINK, Gtk::SHRINK);
242 Gtk::Label *bonus = new Gtk::Label(_("Bonus"));
243 stack_table->attach(*manage(bonus), 6, 7, 0, 1, Gtk::SHRINK, Gtk::SHRINK);
245 std::list<Stack*> stks;
246 stks = stile->getFriendlyStacks(Playerlist::getActiveplayer());
247 currently_selected_stack = stks.front();
248 for (std::list<Stack *>::iterator i = stks.begin(); i != stks.end(); i++)
252 stack_table->show_all();
255 bool StackInfoDialog::on_army_button_event(GdkEventButton *e, Gtk::ToggleButton *toggle)
257 MouseButtonEvent event = to_input_event(e);
258 if (event.button == MouseButtonEvent::RIGHT_BUTTON
259 && event.state == MouseButtonEvent::PRESSED)
262 for (unsigned int i = 0; i < toggles.size(); ++i)
264 if (toggle == toggles[i])
269 const Army *army = armies[slot];
273 if (army_info_tip != NULL)
274 delete army_info_tip;
275 army_info_tip = new ArmyInfoTip(toggle, army);
279 else if (event.button == MouseButtonEvent::RIGHT_BUTTON
280 && event.state == MouseButtonEvent::RELEASED)
282 if (army_info_tip != NULL)
284 delete army_info_tip;
285 army_info_tip = NULL;
293 void StackInfoDialog::on_army_toggled(Gtk::ToggleButton *toggle, Stack *stack, Army *army)
295 Player *p = Playerlist::getActiveplayer();
296 group_button->set_sensitive(false);
297 ungroup_button->set_sensitive(false);
298 if (toggle->get_active() == true)
300 if (stack->size() > 1)
302 Stack *new_stack = p->stackSplitArmy(stack, army);
304 p->stackJoin(currently_selected_stack, new_stack);
307 p->stackJoin(currently_selected_stack, stack);
308 currently_selected_stack->sortForViewing(true);
312 p->stackSplitArmy(stack, army);
313 stack->sortForViewing(true);
315 group_button->set_sensitive(true);
316 ungroup_button->set_sensitive(true);
320 void StackInfoDialog::on_stack_toggled(Gtk::RadioButton *radio, Stack *stack)
322 if (radio->get_active() == true)
324 if (stack == currently_selected_stack)
326 currently_selected_stack = stack;