initial commit, lordsawar source, slightly modified
[lordsawar] / src / editor / tileset-flag-editor-dialog.cpp
1 //  Copyright (C) 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-flag-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 TilesetFlagEditorDialog::TilesetFlagEditorDialog(Tileset *tileset)
36 {
37   selected_filename = "";
38     Glib::RefPtr<Gtk::Builder> xml
39         = Gtk::Builder::create_from_file(get_glade_path()
40                                     + "/tileset-flag-editor-dialog.ui");
41
42     xml->get_widget("dialog", dialog);
43     d_tileset = tileset;
44
45     Gtk::Box *box;
46     xml->get_widget("shieldset_box", box);
47     setup_shield_theme_combobox(box);
48     xml->get_widget("preview_table", preview_table);
49     
50     xml->get_widget("flag_filechooserbutton", flag_filechooserbutton);
51     flag_filechooserbutton->signal_selection_changed().connect
52        (sigc::mem_fun(*this, &TilesetFlagEditorDialog::on_image_chosen));
53
54     update_flag_panel();
55 }
56 TilesetFlagEditorDialog::~TilesetFlagEditorDialog()
57 {
58   delete dialog;
59 }
60
61 void TilesetFlagEditorDialog::set_parent_window(Gtk::Window &parent)
62 {
63     dialog->set_transient_for(parent);
64     //dialog->set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
65 }
66
67 int TilesetFlagEditorDialog::run()
68 {
69     dialog->show_all();
70     int response = dialog->run();
71
72     return response;
73 }
74
75 void TilesetFlagEditorDialog::setup_shield_theme_combobox(Gtk::Box *box)
76 {
77   // fill in shield themes combobox
78   shield_theme_combobox = manage(new Gtk::ComboBoxText);
79
80   Shieldsetlist *sl = Shieldsetlist::getInstance();
81   std::list<std::string> shield_themes = sl->getNames();
82   int counter = 0;
83   int default_id = 0;
84   for (std::list<std::string>::iterator i = shield_themes.begin(),
85        end = shield_themes.end(); i != end; ++i)
86     {
87       if (*i == _("Default"))
88         default_id = counter;
89       shield_theme_combobox->append_text(Glib::filename_to_utf8(*i));
90       counter++;
91     }
92
93   shield_theme_combobox->set_active(default_id);
94   shield_theme_combobox->signal_changed().connect
95     (sigc::mem_fun(this, &TilesetFlagEditorDialog::shieldset_changed));
96
97   box->pack_start(*shield_theme_combobox, Gtk::PACK_SHRINK);
98 }
99     
100 void TilesetFlagEditorDialog::shieldset_changed()
101 {
102 }
103 void TilesetFlagEditorDialog::on_image_chosen()
104 {
105   selected_filename = flag_filechooserbutton->get_filename();
106   if (selected_filename.empty())
107     return;
108
109   show_preview_flags(selected_filename);
110 }
111
112 void TilesetFlagEditorDialog::show_preview_flags(std::string filename)
113 {
114   //load it up and show in the colours of the selected shield theme
115   if (heartbeat.connected())
116     heartbeat.disconnect();
117
118   clearFlag();
119   if (loadFlag(filename) == true)
120     {
121       heartbeat = Glib::signal_timeout().connect
122         (bind_return
123          (sigc::mem_fun (*this, &TilesetFlagEditorDialog::on_heartbeat), 
124           true), 250);
125     }
126 }
127
128 void TilesetFlagEditorDialog::clearFlag()
129 {
130   for (std::map< guint32, std::list<Glib::RefPtr<Gdk::Pixbuf> >* >::iterator it = flags.begin();
131        it != flags.end(); it++)
132     {
133       for (std::list<Glib::RefPtr<Gdk::Pixbuf> >::iterator lit = (*it).second->begin(); lit != (*it).second->end(); lit++)
134         {
135           (*lit).clear();
136         }
137       (*it).second->clear();
138       delete ((*it).second);
139     }
140   flags.clear();
141 }
142
143 bool TilesetFlagEditorDialog::loadFlag(std::string filename)
144 {
145   std::vector<PixMask *> images;
146   std::vector<PixMask *> masks;
147   bool success = GraphicsCache::loadFlagImages(filename, d_tileset->getTileSize(), images, masks);
148   if (success)
149     {
150       std::string subdir = Shieldsetlist::getInstance()->getShieldsetDir 
151         (Glib::filename_from_utf8(shield_theme_combobox->get_active_text()));
152       Shieldset *shieldset = Shieldsetlist::getInstance()->getShieldset(subdir);
153
154       for (unsigned int i = 0; i < MAX_PLAYERS; i++)
155         {
156           std::list<Glib::RefPtr<Gdk::Pixbuf> > *mylist = new std::list<Glib::RefPtr<Gdk::Pixbuf> >();
157           flags[i] = mylist;
158         }
159
160       for (std::vector<PixMask*>::iterator it = images.begin(), mit = masks.begin(); it != images.end(); it++, mit++)
161         {
162           for (Shieldset::iterator sit = shieldset->begin(); sit != shieldset->end(); sit++)
163             {
164               if ((*sit)->getOwner() == 8) //ignore neutral
165                 continue;
166                 flags[(*sit)->getOwner()]->push_back
167                   (GraphicsCache::applyMask(*it, *mit, (*sit)->getColor(), false)->to_pixbuf());
168                 
169                 frame[(*sit)->getOwner()] = flags[(*sit)->getOwner()]->begin();
170             }
171         }
172
173       for (std::vector<PixMask*>::iterator it = images.begin(); it != images.end(); it++)
174         delete *it;
175       for (std::vector<PixMask*>::iterator it = masks.begin(); it != masks.end(); it++)
176         delete *it;
177
178     }
179
180   return success;
181 }
182
183
184 void TilesetFlagEditorDialog::update_flag_panel()
185 {
186   std::string filename = d_tileset->getFlagsFilename();
187   if (filename != "")
188     flag_filechooserbutton->set_filename
189       (d_tileset->getFile(filename));
190 }
191
192 void TilesetFlagEditorDialog::on_heartbeat()
193 {
194   preview_table->foreach(sigc::mem_fun(preview_table, &Gtk::Container::remove));
195   preview_table->resize(4, 2);
196
197   int x = 0;
198   int y = 0;
199   int count = 0;
200   for (std::map< guint32, std::list<Glib::RefPtr<Gdk::Pixbuf> >* >::iterator it = flags.begin();
201        it != flags.end(); it++)
202     {
203       //make a pixbuf and attach it
204       switch (count)
205         {
206         case 0: x = 0; y = 0; break;
207         case 1: x = 0; y = 1; break;
208         case 2: x = 0; y = 2; break;
209         case 3: x = 0; y = 3; break;
210         case 4: x = 1; y = 0; break;
211         case 5: x = 1; y = 1; break;
212         case 6: x = 1; y = 2; break;
213         case 7: x = 1; y = 3; break;
214         }
215       preview_table->attach(*manage(new Gtk::Image(*frame[count])), y, y+1, x, x+1, Gtk::SHRINK, Gtk::SHRINK, 8, 8);
216   
217       frame[count]++;
218       if (frame[count] == flags[count]->end())
219         frame[count] = flags[count]->begin();
220       count++;
221     }
222   preview_table->show_all();
223
224 }