initial commit, lordsawar source, slightly modified
[lordsawar] / src / editor / tileset-selector-editor-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 <gtkmm.h>
21 #include <sigc++/functors/mem_fun.h>
22 #include <stdlib.h>
23
24 #include "tileset-selector-editor-dialog.h"
25
26 #include "glade-helpers.h"
27 #include "gui/image-helpers.h"
28 #include "ucompose.hpp"
29 #include "defs.h"
30 #include "File.h"
31 #include "shieldsetlist.h"
32 #include "GraphicsCache.h"
33
34
35 TilesetSelectorEditorDialog::TilesetSelectorEditorDialog(Tileset *tileset)
36 {
37     Glib::RefPtr<Gtk::Builder> xml
38         = Gtk::Builder::create_from_file(get_glade_path()
39                                     + "/tileset-selector-editor-dialog.ui");
40
41     xml->get_widget("dialog", dialog);
42     d_tileset = tileset;
43     small_filename = "";
44     if (d_tileset->getSmallSelectorFilename().empty() == false)
45       small_filename = 
46         d_tileset->getFile(d_tileset->getSmallSelectorFilename());
47     large_filename = "";
48     if (d_tileset->getLargeSelectorFilename().empty() == false)
49       large_filename = 
50         d_tileset->getFile(d_tileset->getLargeSelectorFilename());
51
52     Gtk::Box *box;
53     xml->get_widget("shieldset_box", box);
54     setup_shield_theme_combobox(box);
55     xml->get_widget("preview_table", preview_table);
56     
57     xml->get_widget("selector_filechooserbutton", selector_filechooserbutton);
58         
59     if (large_filename.empty() == false)
60       selector_filechooserbutton->set_filename (large_filename);
61     selector_filechooserbutton->signal_selection_changed().connect
62        (sigc::mem_fun(*this, &TilesetSelectorEditorDialog::on_image_chosen));
63
64     xml->get_widget("large_selector_radiobutton", large_selector_radiobutton);
65     large_selector_radiobutton->signal_toggled().connect
66       (sigc::mem_fun(*this, &TilesetSelectorEditorDialog::on_large_toggled));
67     xml->get_widget("small_selector_radiobutton", small_selector_radiobutton);
68     small_selector_radiobutton->signal_toggled().connect
69       (sigc::mem_fun(*this, &TilesetSelectorEditorDialog::on_small_toggled));
70
71     if (large_filename.empty() == false)
72       show_preview_selectors(large_filename);
73 }
74 TilesetSelectorEditorDialog::~TilesetSelectorEditorDialog()
75 {
76   delete dialog;
77 }
78
79 void TilesetSelectorEditorDialog::set_parent_window(Gtk::Window &parent)
80 {
81     dialog->set_transient_for(parent);
82     //dialog->set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
83 }
84
85 int TilesetSelectorEditorDialog::run()
86 {
87     dialog->show_all();
88     int response = dialog->run();
89
90     return response;
91 }
92
93 void TilesetSelectorEditorDialog::setup_shield_theme_combobox(Gtk::Box *box)
94 {
95   // fill in shield themes combobox
96   shield_theme_combobox = manage(new Gtk::ComboBoxText);
97
98   Shieldsetlist *sl = Shieldsetlist::getInstance();
99   std::list<std::string> shield_themes = sl->getNames();
100   int counter = 0;
101   int default_id = 0;
102   for (std::list<std::string>::iterator i = shield_themes.begin(),
103        end = shield_themes.end(); i != end; ++i)
104     {
105       if (*i == _("Default"))
106         default_id = counter;
107       shield_theme_combobox->append_text(Glib::filename_to_utf8(*i));
108       counter++;
109     }
110
111   shield_theme_combobox->set_active(default_id);
112   shield_theme_combobox->signal_changed().connect
113     (sigc::mem_fun(this, &TilesetSelectorEditorDialog::shieldset_changed));
114
115   box->pack_start(*shield_theme_combobox, Gtk::PACK_SHRINK);
116 }
117     
118 void TilesetSelectorEditorDialog::shieldset_changed()
119 {
120 }
121 void TilesetSelectorEditorDialog::on_image_chosen()
122 {
123   std::string selected_filename = selector_filechooserbutton->get_filename();
124   if (selected_filename.empty())
125     return;
126
127   if (large_selector_radiobutton->get_active() == true)
128     large_filename = selected_filename;
129   else if (small_selector_radiobutton->get_active() == true)
130     small_filename = selected_filename;
131   else
132     selected_filename = "";
133   if (selected_filename.empty() == false)
134     show_preview_selectors(selected_filename);
135 }
136
137 void TilesetSelectorEditorDialog::show_preview_selectors(std::string filename)
138 {
139   //load it up and show in the colours of the selected shield theme
140
141   clearSelector();
142   if (loadSelector(filename) == true)
143     {
144       heartbeat = Glib::signal_timeout().connect
145         (bind_return
146          (sigc::mem_fun (*this, &TilesetSelectorEditorDialog::on_heartbeat), 
147           true), TIMER_BIGMAP_SELECTOR);
148     }
149 }
150
151 void TilesetSelectorEditorDialog::clearSelector()
152 {
153   if (heartbeat.connected())
154     heartbeat.disconnect();
155
156   for (std::map< guint32, std::list<Glib::RefPtr<Gdk::Pixbuf> >* >::iterator it = selectors.begin();
157        it != selectors.end(); it++)
158     {
159       for (std::list<Glib::RefPtr<Gdk::Pixbuf> >::iterator lit = (*it).second->begin(); lit != (*it).second->end(); lit++)
160         {
161           (*lit).clear();
162         }
163       (*it).second->clear();
164       delete ((*it).second);
165     }
166   selectors.clear();
167   preview_table->foreach(sigc::mem_fun(preview_table, &Gtk::Container::remove));
168 }
169
170 bool TilesetSelectorEditorDialog::loadSelector(std::string filename)
171 {
172   std::vector<PixMask *> images;
173   std::vector<PixMask *> masks;
174   bool success = GraphicsCache::loadSelectorImages(filename, d_tileset->getTileSize(), images, masks);
175   if (success)
176     {
177       std::string subdir = Shieldsetlist::getInstance()->getShieldsetDir 
178         (Glib::filename_from_utf8(shield_theme_combobox->get_active_text()));
179       Shieldset *shieldset = Shieldsetlist::getInstance()->getShieldset(subdir);
180
181       for (unsigned int i = 0; i < MAX_PLAYERS; i++)
182         {
183           std::list<Glib::RefPtr<Gdk::Pixbuf> > *mylist = new std::list<Glib::RefPtr<Gdk::Pixbuf> >();
184           selectors[i] = mylist;
185         }
186
187       for (std::vector<PixMask*>::iterator it = images.begin(), mit = masks.begin(); it != images.end(); it++, mit++)
188         {
189           for (Shieldset::iterator sit = shieldset->begin(); sit != shieldset->end(); sit++)
190             {
191               if ((*sit)->getOwner() == 8) //ignore neutral
192                 continue;
193                 selectors[(*sit)->getOwner()]->push_back
194                   (GraphicsCache::applyMask(*it, *mit, (*sit)->getColor(), false)->to_pixbuf());
195                 
196                 frame[(*sit)->getOwner()] = selectors[(*sit)->getOwner()]->begin();
197             }
198         }
199
200       for (std::vector<PixMask*>::iterator it = images.begin(); it != images.end(); it++)
201         delete *it;
202       for (std::vector<PixMask*>::iterator it = masks.begin(); it != masks.end(); it++)
203         delete *it;
204
205     }
206
207   return success;
208 }
209
210 void TilesetSelectorEditorDialog::on_large_toggled()
211 {
212   update_selector_panel();
213 }
214
215 void TilesetSelectorEditorDialog::on_small_toggled()
216 {
217   update_selector_panel();
218 }
219
220
221 void TilesetSelectorEditorDialog::update_selector_panel()
222 {
223   if (large_selector_radiobutton->get_active() == true)
224     {
225       if (large_filename.empty() == false)
226         selector_filechooserbutton->set_filename (large_filename);
227       else
228         clearSelector();
229     }
230   else if (small_selector_radiobutton->get_active() == true)
231     {
232       if (small_filename.empty() == false)
233         selector_filechooserbutton->set_filename (small_filename);
234       else
235         clearSelector();
236
237     }
238
239 }
240
241 void TilesetSelectorEditorDialog::on_heartbeat()
242 {
243   preview_table->foreach(sigc::mem_fun(preview_table, &Gtk::Container::remove));
244   preview_table->resize(4, 2);
245
246   int x = 0;
247   int y = 0;
248   int count = 0;
249   for (std::map< guint32, std::list<Glib::RefPtr<Gdk::Pixbuf> >* >::iterator it = selectors.begin();
250        it != selectors.end(); it++)
251     {
252       //make a pixbuf and attach it
253       switch (count)
254         {
255         case 0: x = 0; y = 0; break;
256         case 1: x = 0; y = 1; break;
257         case 2: x = 0; y = 2; break;
258         case 3: x = 0; y = 3; break;
259         case 4: x = 1; y = 0; break;
260         case 5: x = 1; y = 1; break;
261         case 6: x = 1; y = 2; break;
262         case 7: x = 1; y = 3; break;
263         }
264       preview_table->attach(*manage(new Gtk::Image(*frame[count])), y, y+1, x, x+1, Gtk::SHRINK, Gtk::SHRINK, 8, 8);
265   
266       frame[count]++;
267       if (frame[count] == selectors[count]->end())
268         frame[count] = selectors[count]->begin();
269       count++;
270     }
271   preview_table->show_all();
272
273 }