initial commit, lordsawar source, slightly modified
[lordsawar] / src / editor / itemlist-dialog.cpp
1 //  Copyright (C) 2008, 2009 Ben Asselstine
2 //
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.
7 //
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.
12 //
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 
16 //  02110-1301, USA.
17
18 #include <config.h>
19
20 #include <iostream>
21 #include <iomanip>
22 #include <assert.h>
23 #include <libgen.h>
24
25 #include <sigc++/functors/mem_fun.h>
26 #include <sigc++/functors/ptr_fun.h>
27
28 #include <gtkmm.h>
29 #include "itemlist-dialog.h"
30
31 #include "gui/input-helpers.h"
32 #include "gui/error-utils.h"
33
34 #include "defs.h"
35 #include "Configuration.h"
36 #include "Itemlist.h"
37 #include "Tile.h"
38
39 #include "ucompose.hpp"
40
41 #include "glade-helpers.h"
42
43
44 ItemlistDialog::ItemlistDialog()
45 {
46   d_itemlist = Itemlist::getInstance();
47     Glib::RefPtr<Gtk::Builder> xml
48         = Gtk::Builder::create_from_file(get_glade_path() + 
49                                     "/itemlist-dialog.ui");
50
51     xml->get_widget("dialog", dialog);
52
53     xml->get_widget("name_entry", name_entry);
54     name_entry->signal_changed().connect
55       (sigc::mem_fun(this, &ItemlistDialog::on_name_changed));
56     xml->get_widget("items_treeview", items_treeview);
57     xml->get_widget("add_item_button", add_item_button);
58     add_item_button->signal_clicked().connect
59       (sigc::mem_fun(this, &ItemlistDialog::on_add_item_clicked));
60     xml->get_widget("remove_item_button", remove_item_button);
61     remove_item_button->signal_clicked().connect
62       (sigc::mem_fun(this, &ItemlistDialog::on_remove_item_clicked));
63     xml->get_widget("item_vbox", item_vbox);
64
65     items_list = Gtk::ListStore::create(items_columns);
66     items_treeview->set_model(items_list);
67     items_treeview->append_column("", items_columns.name);
68     items_treeview->set_headers_visible(false);
69
70     Itemlist::iterator iter = d_itemlist->begin();
71     for (;iter != d_itemlist->end(); iter++)
72       addItemProto((*iter).second);
73       
74     guint32 max = d_itemlist->size();
75     if (max)
76       {
77         Gtk::TreeModel::Row row;
78         row = items_treeview->get_model()->children()[0];
79         if(row)
80           items_treeview->get_selection()->select(row);
81       }
82
83     xml->get_widget("add1str_checkbutton", add1str_checkbutton);
84     add1str_checkbutton->signal_toggled().connect(
85         sigc::mem_fun(this, &ItemlistDialog::on_add1str_toggled));
86     xml->get_widget("add2str_checkbutton", add2str_checkbutton);
87     add2str_checkbutton->signal_toggled().connect(
88         sigc::mem_fun(this, &ItemlistDialog::on_add2str_toggled));
89     xml->get_widget("add3str_checkbutton", add3str_checkbutton);
90     add3str_checkbutton->signal_toggled().connect(
91         sigc::mem_fun(this, &ItemlistDialog::on_add3str_toggled));
92     xml->get_widget("add1stack_checkbutton", add1stack_checkbutton);
93     add1stack_checkbutton->signal_toggled().connect(
94         sigc::mem_fun(this, &ItemlistDialog::on_add1stack_toggled));
95     xml->get_widget("add2stack_checkbutton", add2stack_checkbutton);
96     add2stack_checkbutton->signal_toggled().connect(
97         sigc::mem_fun(this, &ItemlistDialog::on_add2stack_toggled));
98     xml->get_widget("add3stack_checkbutton", add3stack_checkbutton);
99     add3stack_checkbutton->signal_toggled().connect(
100         sigc::mem_fun(this, &ItemlistDialog::on_add3stack_toggled));
101     xml->get_widget("flystack_checkbutton", flystack_checkbutton);
102     flystack_checkbutton->signal_toggled().connect(
103         sigc::mem_fun(this, &ItemlistDialog::on_flystack_toggled));
104     xml->get_widget("doublemovestack_checkbutton", doublemovestack_checkbutton);
105     doublemovestack_checkbutton->signal_toggled().connect(
106         sigc::mem_fun(this, &ItemlistDialog::on_doublemovestack_toggled));
107     xml->get_widget("add2goldpercity_checkbutton", add2goldpercity_checkbutton);
108     add2goldpercity_checkbutton->signal_toggled().connect(
109         sigc::mem_fun(this, &ItemlistDialog::on_add2goldpercity_toggled));
110     xml->get_widget("add3goldpercity_checkbutton", add3goldpercity_checkbutton);
111     add3goldpercity_checkbutton->signal_toggled().connect(
112         sigc::mem_fun(this, &ItemlistDialog::on_add3goldpercity_toggled));
113     xml->get_widget("add4goldpercity_checkbutton", add4goldpercity_checkbutton);
114     add4goldpercity_checkbutton->signal_toggled().connect(
115         sigc::mem_fun(this, &ItemlistDialog::on_add4goldpercity_toggled));
116     xml->get_widget("add5goldpercity_checkbutton", add5goldpercity_checkbutton);
117     add5goldpercity_checkbutton->signal_toggled().connect(
118         sigc::mem_fun(this, &ItemlistDialog::on_add5goldpercity_toggled));
119
120     update_item_panel();
121     update_itemlist_buttons();
122     items_treeview->get_selection()->signal_changed().connect
123       (sigc::mem_fun(*this, &ItemlistDialog::on_item_selected));
124 }
125
126 void
127 ItemlistDialog::update_itemlist_buttons()
128 {
129   if (!items_treeview->get_selection()->get_selected())
130     remove_item_button->set_sensitive(false);
131   else
132     remove_item_button->set_sensitive(true);
133   if (d_itemlist == NULL)
134     add_item_button->set_sensitive(false);
135   else
136     add_item_button->set_sensitive(true);
137 }
138
139 void
140 ItemlistDialog::update_item_panel()
141 {
142   //if nothing selected in the treeview, then we don't show anything in
143   //the item panel
144   if (items_treeview->get_selection()->get_selected() == 0)
145     {
146       //clear all values
147       name_entry->set_text("");
148       item_vbox->set_sensitive(false);
149       return;
150     }
151   item_vbox->set_sensitive(true);
152   Glib::RefPtr<Gtk::TreeSelection> selection = items_treeview->get_selection();
153   Gtk::TreeModel::iterator iterrow = selection->get_selected();
154
155   if (iterrow) 
156     {
157       // Row selected
158       Gtk::TreeModel::Row row = *iterrow;
159
160       ItemProto *a = row[items_columns.item];
161       fill_item_info(a);
162     }
163 }
164
165 ItemlistDialog::~ItemlistDialog()
166 {
167   delete dialog;
168 }
169
170 void ItemlistDialog::show()
171 {
172   dialog->show();
173 }
174
175 void ItemlistDialog::hide()
176 {
177   dialog->hide();
178 }
179
180 void ItemlistDialog::addItemProto(ItemProto *itemproto)
181 {
182   Gtk::TreeIter i = items_list->append();
183   (*i)[items_columns.name] = itemproto->getName();
184   (*i)[items_columns.item] = itemproto;
185 }
186
187 void ItemlistDialog::on_item_selected()
188 {
189   update_item_panel();
190   update_itemlist_buttons();
191 }
192
193 static int inhibit_bonus_checkbuttons;
194
195 void ItemlistDialog::fill_item_info(ItemProto *item)
196 {
197   name_entry->set_text(item->getName());
198   inhibit_bonus_checkbuttons = 1;
199   add1str_checkbutton->set_active(item->getBonus(ItemProto::ADD1STR));
200   add2str_checkbutton->set_active(item->getBonus(ItemProto::ADD2STR));
201   add3str_checkbutton->set_active(item->getBonus(ItemProto::ADD3STR));
202   add1stack_checkbutton->set_active(item->getBonus(ItemProto::ADD1STACK));
203   add2stack_checkbutton->set_active(item->getBonus(ItemProto::ADD2STACK));
204   add3stack_checkbutton->set_active(item->getBonus(ItemProto::ADD3STACK));
205   flystack_checkbutton->set_active(item->getBonus(ItemProto::FLYSTACK));
206   doublemovestack_checkbutton->set_active 
207     (item->getBonus(ItemProto::DOUBLEMOVESTACK));
208   add2goldpercity_checkbutton->set_active
209     (item->getBonus(ItemProto::ADD2GOLDPERCITY));
210   add3goldpercity_checkbutton->set_active
211     (item->getBonus(ItemProto::ADD3GOLDPERCITY));
212   add4goldpercity_checkbutton->set_active
213     (item->getBonus(ItemProto::ADD4GOLDPERCITY));
214   add5goldpercity_checkbutton->set_active
215     (item->getBonus(ItemProto::ADD5GOLDPERCITY));
216   inhibit_bonus_checkbuttons = 0;
217 }
218
219 void ItemlistDialog::on_name_changed()
220 {
221   Glib::RefPtr<Gtk::TreeSelection> selection = items_treeview->get_selection();
222   Gtk::TreeModel::iterator iterrow = selection->get_selected();
223
224   if (iterrow) 
225     {
226       Gtk::TreeModel::Row row = *iterrow;
227       ItemProto *a = row[items_columns.item];
228       a->setName(name_entry->get_text());
229       row[items_columns.name] = name_entry->get_text();
230     }
231 }
232 void ItemlistDialog::on_add_item_clicked()
233 {
234   //add a new empty item to the itemlist
235   ItemProto *a = new ItemProto("Untitled", 0);
236   //add it to the treeview
237   Gtk::TreeIter i = items_list->append();
238   a->setName("Untitled");
239   (*i)[items_columns.name] = a->getName();
240   (*i)[items_columns.item] = a;
241
242 }
243 void ItemlistDialog::on_remove_item_clicked()
244 {
245   //erase the selected row from the treeview
246   //remove the item from the itemlist
247   Glib::RefPtr<Gtk::TreeSelection> selection = items_treeview->get_selection();
248   Gtk::TreeModel::iterator iterrow = selection->get_selected();
249
250   if (iterrow) 
251     {
252       Gtk::TreeModel::Row row = *iterrow;
253       ItemProto *a = row[items_columns.item];
254       items_list->erase(iterrow);
255       d_itemlist->remove(a);
256     }
257 }
258 void ItemlistDialog::set_parent_window(Gtk::Window &parent)
259 {
260     dialog->set_transient_for(parent);
261     //dialog->set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
262 }
263
264 int ItemlistDialog::run()
265 {
266     dialog->show_all();
267     return dialog->run();
268 }
269
270 void ItemlistDialog::on_checkbutton_toggled(Gtk::CheckButton *checkbutton, 
271                                             ItemProto::Bonus bonus)
272 {
273   if (inhibit_bonus_checkbuttons)
274     return;
275   Glib::RefPtr<Gtk::TreeSelection> selection = items_treeview->get_selection();
276   Gtk::TreeModel::iterator iterrow = selection->get_selected();
277
278   if (iterrow) 
279     {
280       // Row selected
281       Gtk::TreeModel::Row row = *iterrow;
282       d_item = row[items_columns.item];
283     }
284   else
285     return;
286   if (checkbutton->get_active())
287     d_item->addBonus(bonus);
288   else
289     d_item->removeBonus(bonus);
290 }
291
292 void ItemlistDialog::on_add1str_toggled()
293 {
294   on_checkbutton_toggled(add1str_checkbutton, ItemProto::ADD1STR);
295 }
296
297 void ItemlistDialog::on_add2str_toggled()
298 {
299   on_checkbutton_toggled(add2str_checkbutton, ItemProto::ADD2STR);
300 }
301
302 void ItemlistDialog::on_add3str_toggled()
303 {
304   on_checkbutton_toggled(add3str_checkbutton, ItemProto::ADD3STR);
305 }
306
307 void ItemlistDialog::on_add1stack_toggled()
308 {
309   on_checkbutton_toggled(add1stack_checkbutton, ItemProto::ADD1STACK);
310 }
311
312 void ItemlistDialog::on_add2stack_toggled()
313 {
314   on_checkbutton_toggled(add2stack_checkbutton, ItemProto::ADD2STACK);
315 }
316
317 void ItemlistDialog::on_add3stack_toggled()
318 {
319   on_checkbutton_toggled(add3stack_checkbutton, ItemProto::ADD3STACK);
320 }
321
322 void ItemlistDialog::on_flystack_toggled()
323 {
324   on_checkbutton_toggled(flystack_checkbutton, ItemProto::FLYSTACK);
325 }
326
327 void ItemlistDialog::on_doublemovestack_toggled()
328 {
329   on_checkbutton_toggled(doublemovestack_checkbutton, ItemProto::DOUBLEMOVESTACK);
330 }
331
332 void ItemlistDialog::on_add2goldpercity_toggled()
333 {
334   on_checkbutton_toggled(add2goldpercity_checkbutton, ItemProto::ADD2GOLDPERCITY);
335 }
336
337 void ItemlistDialog::on_add3goldpercity_toggled()
338 {
339   on_checkbutton_toggled(add2goldpercity_checkbutton, ItemProto::ADD3GOLDPERCITY);
340 }
341
342 void ItemlistDialog::on_add4goldpercity_toggled()
343 {
344   on_checkbutton_toggled(add4goldpercity_checkbutton, ItemProto::ADD4GOLDPERCITY);
345 }
346
347 void ItemlistDialog::on_add5goldpercity_toggled()
348 {
349   on_checkbutton_toggled(add5goldpercity_checkbutton, ItemProto::ADD5GOLDPERCITY);
350 }