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
27 #include <sigc++/functors/mem_fun.h>
28 #include <sigc++/functors/ptr_fun.h>
29 #include "ucompose.hpp"
32 #include "tileset-window.h"
33 #include "tileset-info-dialog.h"
34 #include "tile-preview-dialog.h"
35 #include "tileset-selector-editor-dialog.h"
36 #include "tileset-flag-editor-dialog.h"
37 #include "tileset-explosion-picture-editor-dialog.h"
38 #include "image-editor-dialog.h"
40 #include "image-helpers.h"
41 #include "input-helpers.h"
42 #include "error-utils.h"
45 #include "Configuration.h"
46 #include "tilesetlist.h"
49 #include "overviewmap.h"
50 #include "GraphicsCache.h"
52 #include "ucompose.hpp"
54 #include "glade-helpers.h"
57 TileSetWindow::TileSetWindow(std::string load_filename)
61 Glib::RefPtr<Gtk::Builder> xml
62 = Gtk::Builder::create_from_file(get_glade_path() + "/tileset-window.ui");
64 xml->get_widget("window", window);
65 window->set_icon_from_file(File::getMiscFile("various/tileset_icon.png"));
66 window->signal_delete_event().connect
67 (sigc::mem_fun(*this, &TileSetWindow::on_window_closed));
69 xml->get_widget("tiles_treeview", tiles_treeview);
70 xml->get_widget("tile_name_entry", tile_name_entry);
71 tile_name_entry->signal_changed().connect
72 (sigc::mem_fun(this, &TileSetWindow::on_tile_name_changed));
74 Gtk::HBox *type_combo_container;
75 xml->get_widget("type_combo_container", type_combo_container);
76 tile_type_combobox = new Gtk::ComboBoxText();
77 tile_type_combobox->append_text(_("Grass"));
78 tile_type_combobox->append_text(_("Water"));
79 tile_type_combobox->append_text(_("Forest"));
80 tile_type_combobox->append_text(_("Hills"));
81 tile_type_combobox->append_text(_("Mountains"));
82 tile_type_combobox->append_text(_("Swamp"));
83 tile_type_combobox->append_text(_("Void"));
84 type_combo_container->add(*manage(tile_type_combobox));
85 type_combo_container->show_all();
86 tile_type_combobox->signal_changed().connect
87 (sigc::mem_fun(this, &TileSetWindow::on_tile_type_changed));
89 Gtk::HBox *tilestyle_combo_container;
90 xml->get_widget("tilestyle_combo_container", tilestyle_combo_container);
91 tilestyle_combobox = new Gtk::ComboBoxText();
92 tilestyle_combobox->append_text(_("Lone"));
93 tilestyle_combobox->append_text(_("Outer Top-Left"));
94 tilestyle_combobox->append_text(_("Outer Top-Center"));
95 tilestyle_combobox->append_text(_("Outer Top-Right"));
96 tilestyle_combobox->append_text(_("Outer Bottom-Left"));
97 tilestyle_combobox->append_text(_("Outer Bottom-Center"));
98 tilestyle_combobox->append_text(_("Outer Bottom-Right"));
99 tilestyle_combobox->append_text(_("Outer Middle-Left"));
100 tilestyle_combobox->append_text(_("Inner Middle-Center"));
101 tilestyle_combobox->append_text(_("Outer Middle-Right"));
102 tilestyle_combobox->append_text(_("Inner Top-Left"));
103 tilestyle_combobox->append_text(_("Inner Top-Right"));
104 tilestyle_combobox->append_text(_("Inner Bottom-Left"));
105 tilestyle_combobox->append_text(_("Inner Bottom-Right"));
106 tilestyle_combobox->append_text(_("Top-Left To Bottom-Right"));
107 tilestyle_combobox->append_text(_("Bottom-Left To Top-Right"));
108 tilestyle_combobox->append_text(_("Other"));
109 tilestyle_combo_container->add(*manage(tilestyle_combobox));
110 tilestyle_combo_container->show_all();
111 tilestyle_combobox->signal_changed().connect
112 (sigc::mem_fun(this, &TileSetWindow::on_tilestyle_changed));
114 Gtk::HBox *pattern_container;
115 xml->get_widget("pattern_container", pattern_container);
116 tile_smallmap_pattern_combobox = new Gtk::ComboBoxText();
117 tile_smallmap_pattern_combobox->append_text(_("Solid"));
118 tile_smallmap_pattern_combobox->append_text(_("Stippled"));
119 tile_smallmap_pattern_combobox->append_text(_("Randomized"));
120 tile_smallmap_pattern_combobox->append_text(_("Sunken"));
121 tile_smallmap_pattern_combobox->append_text(_("Tablecloth"));
122 tile_smallmap_pattern_combobox->append_text(_("Diagonal"));
123 tile_smallmap_pattern_combobox->append_text(_("Crosshatched"));
124 tile_smallmap_pattern_combobox->append_text(_("Sunken Striped"));
125 pattern_container->add(*manage(tile_smallmap_pattern_combobox));
126 pattern_container->show_all();
127 tile_smallmap_pattern_combobox->signal_changed().connect
128 (sigc::mem_fun(this, &TileSetWindow::on_tile_pattern_changed));
130 xml->get_widget("tile_moves_spinbutton", tile_moves_spinbutton);
131 xml->get_widget("tile_smallmap_first_colorbutton",
132 tile_smallmap_first_colorbutton);
133 tile_smallmap_first_colorbutton->signal_color_set().connect
134 (sigc::mem_fun(this, &TileSetWindow::on_tile_first_color_changed));
135 xml->get_widget("tile_smallmap_second_colorbutton",
136 tile_smallmap_second_colorbutton);
137 tile_smallmap_second_colorbutton->signal_color_set().connect
138 (sigc::mem_fun(this, &TileSetWindow::on_tile_second_color_changed));
139 xml->get_widget("tile_smallmap_third_colorbutton",
140 tile_smallmap_third_colorbutton);
141 tile_smallmap_third_colorbutton->signal_color_set().connect
142 (sigc::mem_fun(this, &TileSetWindow::on_tile_third_color_changed));
143 xml->get_widget("tile_smallmap_image", tile_smallmap_image);
145 xml->get_widget("add_tile_button", add_tile_button);
146 add_tile_button->signal_clicked().connect
147 (sigc::mem_fun(this, &TileSetWindow::on_add_tile_clicked));
148 xml->get_widget("remove_tile_button", remove_tile_button);
149 remove_tile_button->signal_clicked().connect
150 (sigc::mem_fun(this, &TileSetWindow::on_remove_tile_clicked));
151 xml->get_widget("tile_vbox", tile_vbox);
152 // connect callbacks for the menu
153 xml->get_widget("new_tileset_menuitem", new_tileset_menuitem);
154 new_tileset_menuitem->signal_activate().connect
155 (sigc::mem_fun(this, &TileSetWindow::on_new_tileset_activated));
156 xml->get_widget("load_tileset_menuitem", load_tileset_menuitem);
157 load_tileset_menuitem->signal_activate().connect
158 (sigc::mem_fun(this, &TileSetWindow::on_load_tileset_activated));
159 xml->get_widget("save_tileset_menuitem", save_tileset_menuitem);
160 save_tileset_menuitem->signal_activate().connect
161 (sigc::mem_fun(this, &TileSetWindow::on_save_tileset_activated));
162 xml->get_widget("quit_menuitem", quit_menuitem);
163 quit_menuitem->signal_activate().connect
164 (sigc::mem_fun(this, &TileSetWindow::on_quit_activated));
165 xml->get_widget("edit_tileset_info_menuitem", edit_tileset_info_menuitem);
166 edit_tileset_info_menuitem->signal_activate().connect
167 (sigc::mem_fun(this, &TileSetWindow::on_edit_tileset_info_activated));
168 xml->get_widget("army_unit_selector_menuitem", army_unit_selector_menuitem);
169 army_unit_selector_menuitem->signal_activate().connect
170 (sigc::mem_fun(this, &TileSetWindow::on_army_unit_selector_activated));
171 xml->get_widget("roads_picture_menuitem", roads_picture_menuitem);
172 roads_picture_menuitem->signal_activate().connect
173 (sigc::mem_fun(this, &TileSetWindow::on_roads_picture_activated));
174 xml->get_widget("bridges_picture_menuitem", bridges_picture_menuitem);
175 bridges_picture_menuitem->signal_activate().connect
176 (sigc::mem_fun(this, &TileSetWindow::on_bridges_picture_activated));
177 xml->get_widget("fog_picture_menuitem", fog_picture_menuitem);
178 fog_picture_menuitem->signal_activate().connect
179 (sigc::mem_fun(this, &TileSetWindow::on_fog_picture_activated));
180 xml->get_widget("flags_picture_menuitem", flags_picture_menuitem);
181 flags_picture_menuitem->signal_activate().connect
182 (sigc::mem_fun(this, &TileSetWindow::on_flags_picture_activated));
184 xml->get_widget("explosion_picture_menuitem", explosion_picture_menuitem);
185 explosion_picture_menuitem->signal_activate().connect
186 (sigc::mem_fun(this, &TileSetWindow::on_explosion_picture_activated));
187 xml->get_widget("preview_tile_menuitem", preview_tile_menuitem);
188 preview_tile_menuitem->signal_activate().connect
189 (sigc::mem_fun(this, &TileSetWindow::on_preview_tile_activated));
190 xml->get_widget ("help_about_menuitem", help_about_menuitem);
191 help_about_menuitem->signal_activate().connect
192 (sigc::mem_fun(this, &TileSetWindow::on_help_about_activated));
193 xml->get_widget("tilestyle_image", tilestyle_image);
195 window->signal_delete_event().connect
196 (sigc::mem_fun(*this, &TileSetWindow::on_delete_event));
198 tiles_list = Gtk::ListStore::create(tiles_columns);
199 tiles_treeview->set_model(tiles_list);
200 tiles_treeview->append_column("", tiles_columns.name);
201 tiles_treeview->set_headers_visible(false);
202 tiles_treeview->get_selection()->signal_changed().connect
203 (sigc::mem_fun(*this, &TileSetWindow::on_tile_selected));
205 xml->get_widget("tilestylesets_treeview", tilestylesets_treeview);
206 tilestylesets_list = Gtk::ListStore::create(tilestylesets_columns);
207 tilestylesets_treeview->set_model(tilestylesets_list);
208 tilestylesets_treeview->append_column("", tilestylesets_columns.name);
209 tilestylesets_treeview->set_headers_visible(false);
210 tilestylesets_treeview->get_selection()->signal_changed().connect
211 (sigc::mem_fun(*this, &TileSetWindow::on_tilestyleset_selected));
213 xml->get_widget("tilestyles_treeview", tilestyles_treeview);
214 tilestyles_list = Gtk::ListStore::create(tilestyles_columns);
215 tilestyles_treeview->set_model(tilestyles_list);
216 tilestyles_treeview->append_column("", tilestyles_columns.name);
217 tilestyles_treeview->set_headers_visible(false);
218 tilestyles_treeview->get_selection()->signal_changed().connect
219 (sigc::mem_fun(*this, &TileSetWindow::on_tilestyle_selected));
221 xml->get_widget("add_tilestyleset_button", add_tilestyleset_button);
222 add_tilestyleset_button->signal_clicked().connect
223 (sigc::mem_fun(this, &TileSetWindow::on_add_tilestyleset_clicked));
224 xml->get_widget("remove_tilestyleset_button", remove_tilestyleset_button);
225 remove_tilestyleset_button->signal_clicked().connect
226 (sigc::mem_fun(this, &TileSetWindow::on_remove_tilestyleset_clicked));
227 xml->get_widget("tilestyleset_frame", tilestyleset_frame);
228 xml->get_widget("tilestyle_frame", tilestyle_frame);
229 xml->get_widget("image_filechooser_button", image_filechooser_button);
230 image_filechooser_button->signal_selection_changed().connect
231 (sigc::mem_fun(*this, &TileSetWindow::on_image_chosen));
232 xml->get_widget("refresh_button", refresh_button);
233 refresh_button->signal_clicked().connect
234 (sigc::mem_fun(this, &TileSetWindow::on_refresh_clicked));
236 Gtk::FileFilter sav_filter;
237 sav_filter.add_pattern("*.png");
238 image_filechooser_button->set_filter(sav_filter);
239 image_filechooser_button->set_current_folder (File::getUserTilesetDir());
241 xml->get_widget("tilestyle_standard_image", tilestyle_standard_image);
242 tilestyle_standard_images =
243 disassemble_row(File::getMiscFile("various/editor/tilestyles.png"), 17);
246 update_tilestyleset_panel();
247 update_tilestyle_panel();
248 update_tileset_buttons();
249 update_tilestyleset_buttons();
251 update_tileset_buttons();
252 update_tilestyleset_buttons();
253 update_tileset_menuitems();
254 update_tile_preview_menuitem();
256 tile_smallmap_surface = Gdk::Pixmap::create(Glib::RefPtr<Gdk::Drawable>(0), 32, 32, 24);
257 tile_smallmap_surface_gc = Gdk::GC::create(tile_smallmap_surface);
259 inhibit_image_change = false;
260 if (load_filename.empty() == false)
261 load_tileset(load_filename);
265 TileSetWindow::update_tileset_menuitems()
267 if (d_tileset == NULL)
269 save_tileset_menuitem->set_sensitive(false);
270 army_unit_selector_menuitem->set_sensitive(false);
271 edit_tileset_info_menuitem->set_sensitive(false);
272 explosion_picture_menuitem->set_sensitive(false);
273 roads_picture_menuitem->set_sensitive(false);
274 bridges_picture_menuitem->set_sensitive(false);
275 fog_picture_menuitem->set_sensitive(false);
276 flags_picture_menuitem->set_sensitive(false);
280 save_tileset_menuitem->set_sensitive(true);
281 army_unit_selector_menuitem->set_sensitive(true);
282 edit_tileset_info_menuitem->set_sensitive(true);
283 explosion_picture_menuitem->set_sensitive(true);
284 roads_picture_menuitem->set_sensitive(true);
285 bridges_picture_menuitem->set_sensitive(true);
286 fog_picture_menuitem->set_sensitive(true);
287 flags_picture_menuitem->set_sensitive(true);
292 TileSetWindow::update_tileset_buttons()
294 if (!tiles_treeview->get_selection()->get_selected())
295 remove_tile_button->set_sensitive(false);
297 remove_tile_button->set_sensitive(true);
298 if (d_tileset == NULL)
299 add_tile_button->set_sensitive(false);
301 add_tile_button->set_sensitive(true);
305 TileSetWindow::update_tilestyleset_buttons()
307 if (!tilestylesets_treeview->get_selection()->get_selected())
308 remove_tilestyleset_button->set_sensitive(false);
310 remove_tilestyleset_button->set_sensitive(true);
311 if (d_tileset == NULL)
312 add_tilestyleset_button->set_sensitive(false);
314 add_tilestyleset_button->set_sensitive(true);
318 TileSetWindow::update_tilestyle_panel()
320 if (tilestyles_treeview->get_selection()->get_selected() == 0)
323 tilestyle_frame->set_sensitive(false);
324 tilestyle_combobox->set_active(0);
325 tilestyle_image->clear();
326 tilestyle_standard_image->clear();
327 tilestyle_image->show_all();
331 tilestyle_frame->set_sensitive(true);
332 TileStyle *t = get_selected_tilestyle ();
335 tilestyle_combobox->set_active(t->getType());
336 Glib::RefPtr<Gdk::Pixbuf> pixbuf= t->getImage()->to_pixbuf();
337 tilestyle_image->clear();
338 tilestyle_image->property_pixbuf() = pixbuf;
339 tilestyle_image->show_all();
340 int idx = t->getType();
341 tilestyle_standard_image->property_pixbuf() =
342 tilestyle_standard_images[idx]->to_pixbuf();
346 int get_image_height(std::string filename)
348 Glib::RefPtr<Gdk::Pixbuf> row = Gdk::Pixbuf::create_from_file(filename);
350 return row->get_height();
355 int get_image_width (std::string filename)
357 Glib::RefPtr<Gdk::Pixbuf> row = Gdk::Pixbuf::create_from_file(filename);
359 return row->get_width();
364 void TileSetWindow::fill_tilestyleset_info(TileStyleSet *t)
367 if (t->getSubDir() == "")
368 subdir = d_tileset->getSubDir();
370 subdir = t->getSubDir();
371 std::string n = d_tileset->getFile(t->getName());
372 int height = get_image_height (n);
375 d_tileset->setTileSize(height);
376 TileStyleSet *set = get_selected_tilestyleset ();
377 set->instantiateImages(d_tileset->getTileSize(),
378 d_tileset->getFile(set->getName()));
380 inhibit_image_change = true;
381 image_filechooser_button->set_filename(n);
382 refresh_button->set_sensitive(true);
383 //add the tilestyles to the tilestyles_treeview
384 tilestyles_list->clear();
385 for (unsigned int i = 0; i < t->size(); i++)
387 Gtk::TreeIter l = tilestyles_list->append();
388 (*l)[tilestyles_columns.name] =
389 String::ucompose("0x%1", Glib::ustring::format(std::hex, std::setfill(L'0'), std::setw(2), (*t)[i]->getId()));
390 (*l)[tilestyles_columns.tilestyle] = (*t)[i];
395 TileSetWindow::update_tilestyleset_panel()
397 if (tilestylesets_treeview->get_selection()->get_selected() == 0)
400 tilestyleset_frame->set_sensitive(false);
402 image_filechooser_button->set_current_folder(d_tileset->getDirectory());
404 image_filechooser_button->set_current_folder(File::getUserTilesetDir());
405 tilestyles_list->clear();
406 refresh_button->set_sensitive(false);
409 tilestyleset_frame->set_sensitive(true);
410 TileStyleSet *t = get_selected_tilestyleset ();
411 if (t && t->getName() != "")
413 fill_tilestyleset_info(t);
418 TileSetWindow::update_tile_panel()
420 Gdk::Color black("black");
421 //if nothing selected in the treeview, then we don't show anything in
423 if (tiles_treeview->get_selection()->get_selected() == 0)
426 tile_smallmap_image->clear();
427 tile_vbox->set_sensitive(false);
428 tile_type_combobox->set_active(0);
429 tile_moves_spinbutton->set_value(0);
430 tile_name_entry->set_text("");
431 tile_smallmap_pattern_combobox->set_active(0);
432 tile_smallmap_first_colorbutton->set_color(black);
433 tile_smallmap_second_colorbutton->set_color(black);
434 tile_smallmap_third_colorbutton->set_color(black);
435 tilestylesets_list->clear();
438 tile_vbox->set_sensitive(true);
439 Tile *t = get_selected_tile ();
443 tile_smallmap_first_colorbutton->set_color(black);
444 tile_smallmap_second_colorbutton->set_color(black);
445 tile_smallmap_third_colorbutton->set_color(black);
449 TileSetWindow::~TileSetWindow()
451 tile_smallmap_surface.reset();
455 void TileSetWindow::show()
460 void TileSetWindow::hide()
465 bool TileSetWindow::on_delete_event(GdkEventAny *e)
473 void TileSetWindow::on_new_tileset_activated()
475 std::string name = "";
476 int id = Tilesetlist::getNextAvailableId(0);
477 Tileset *tileset = new Tileset(id, name);
478 TileSetInfoDialog d(tileset, false);
479 d.set_parent_window(*window);
480 int response = d.run();
481 if (response != Gtk::RESPONSE_ACCEPT)
491 std::string dir = File::getUserTilesetDir() + d_tileset->getSubDir();
492 d_tileset->setDirectory(dir);
493 File::create_dir(dir);
494 current_save_filename = d_tileset->getConfigurationFile();
497 update_tileset_buttons();
498 update_tilestyleset_buttons();
499 update_tileset_menuitems();
500 update_tile_preview_menuitem();
502 XML_Helper helper(current_save_filename, std::ios::out, false);
503 d_tileset->save(&helper);
508 void TileSetWindow::on_load_tileset_activated()
510 Gtk::FileChooserDialog chooser(*window,
511 _("Choose a Tileset to Load"));
512 Gtk::FileFilter sav_filter;
513 sav_filter.add_pattern("*" + TILESET_EXT);
514 chooser.set_filter(sav_filter);
515 chooser.set_current_folder(File::getUserTilesetDir());
517 chooser.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
518 chooser.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
519 chooser.set_default_response(Gtk::RESPONSE_ACCEPT);
522 int res = chooser.run();
524 if (res == Gtk::RESPONSE_ACCEPT)
526 load_tileset(chooser.get_filename());
531 void TileSetWindow::on_save_tileset_activated()
533 if (current_save_filename.empty())
534 current_save_filename = d_tileset->getConfigurationFile();
535 needs_saving = false;
537 //Reorder the tileset according to the treeview
539 for (Gtk::TreeIter i = tiles_list->children().begin(),
540 end = tiles_list->children().end(); i != end; ++i)
541 d_tileset->push_back((*i)[tiles_columns.tile]);
543 XML_Helper helper(current_save_filename, std::ios::out, false);
544 d_tileset->save(&helper);
548 bool TileSetWindow::quit()
553 Glib::RefPtr<Gtk::Builder> xml
554 = Gtk::Builder::create_from_file(get_glade_path() +
555 "/editor-quit-dialog.ui");
556 xml->get_widget("dialog", dialog);
557 dialog->set_transient_for(*window);
558 int response = dialog->run();
562 if (response == Gtk::RESPONSE_CANCEL) //we don't want to quit
565 else if (response == Gtk::RESPONSE_ACCEPT) // save and quit
566 on_save_tileset_activated();
567 //else if (Response == Gtk::CLOSE) // don't save just quit
575 bool TileSetWindow::on_window_closed(GdkEventAny *event)
580 void TileSetWindow::on_quit_activated()
585 void TileSetWindow::on_edit_tileset_info_activated()
587 TileSetInfoDialog d(d_tileset, true);
588 d.set_parent_window(*window);
589 int response = d.run();
590 if (response == Gtk::RESPONSE_ACCEPT)
594 void TileSetWindow::on_help_about_activated()
596 Gtk::AboutDialog* dialog;
598 Glib::RefPtr<Gtk::Builder> xml
599 = Gtk::Builder::create_from_file(get_glade_path() + "/../about-dialog.ui");
601 xml->get_widget("dialog", dialog);
602 dialog->set_transient_for(*window);
603 dialog->set_icon_from_file(File::getMiscFile("various/tileset_icon.png"));
605 dialog->set_version(PACKAGE_VERSION);
606 dialog->set_logo(GraphicsCache::getMiscPicture("tileset_icon.png")->to_pixbuf());
615 void TileSetWindow::update_tile_preview_menuitem()
617 if (get_selected_tile())
618 preview_tile_menuitem->set_sensitive(true);
620 preview_tile_menuitem->set_sensitive(false);
623 void TileSetWindow::on_tile_selected()
626 update_tilestyleset_panel();
627 update_tilestyle_panel();
628 update_tileset_buttons();
629 update_tilestyleset_buttons();
630 update_tile_preview_menuitem();
633 void TileSetWindow::on_tilestyleset_selected()
635 update_tilestyleset_panel();
636 update_tilestyle_panel();
637 update_tilestyleset_buttons();
640 void TileSetWindow::on_tilestyle_selected()
642 update_tilestyle_panel();
645 void TileSetWindow::fill_tilestylesets()
647 Tile *t = get_selected_tile();
650 tilestylesets_list->clear();
651 for (std::list<TileStyleSet*>::iterator it = t->begin(); it != t->end(); it++)
653 Gtk::TreeIter l = tilestylesets_list->append();
654 (*l)[tilestylesets_columns.name] = (*it)->getName();
655 (*l)[tilestylesets_columns.subdir] = (*it)->getSubDir();
656 (*l)[tilestylesets_columns.tilestyleset] = *it;
660 void TileSetWindow::fill_tile_info(Tile *tile)
662 tile_name_entry->set_text(tile->getName());
663 tile_type_combobox->set_active(tile->getTypeIndex());
664 tile_moves_spinbutton->set_value(tile->getMoves());
665 tile_smallmap_pattern_combobox->set_active(tile->getSmallTile()->getPattern());
666 tile_smallmap_first_colorbutton->set_sensitive(true);
667 fill_tilestylesets();
669 fill_tile_smallmap(tile);
672 void TileSetWindow::on_add_tile_clicked()
674 //add a new empty tile to the tileset
675 Tile *t = new Tile();
676 //add it to the treeview
677 Gtk::TreeIter i = tiles_list->append();
678 t->setName("Untitled");
679 (*i)[tiles_columns.name] = t->getName();
680 (*i)[tiles_columns.tile] = t;
681 d_tileset->push_back(t);
682 tiles_treeview->set_cursor (Gtk::TreePath (String::ucompose("%1", d_tileset->size() - 1)));
683 update_tile_preview_menuitem();
687 void TileSetWindow::on_remove_tile_clicked()
689 //erase the selected row from the treeview
690 //remove the tile from the tileset
691 Glib::RefPtr<Gtk::TreeSelection> selection = tiles_treeview->get_selection();
692 Gtk::TreeModel::iterator iterrow = selection->get_selected();
696 Gtk::TreeModel::Row row = *iterrow;
697 Tile *a = row[tiles_columns.tile];
698 tiles_list->erase(iterrow);
700 for (std::vector<Tile*>::iterator it = d_tileset->begin(); it != d_tileset->end(); it++)
704 d_tileset->erase(it);
711 update_tile_preview_menuitem();
714 void TileSetWindow::on_tile_first_color_changed()
716 Glib::RefPtr<Gtk::TreeSelection> selection = tiles_treeview->get_selection();
717 Gtk::TreeModel::iterator iterrow = selection->get_selected();
721 Gtk::TreeModel::Row row = *iterrow;
722 Tile *t = row[tiles_columns.tile];
723 t->getSmallTile()->setColor(tile_smallmap_first_colorbutton->get_color());
724 fill_tile_smallmap(t);
729 void TileSetWindow::on_tile_second_color_changed()
731 Glib::RefPtr<Gtk::TreeSelection> selection = tiles_treeview->get_selection();
732 Gtk::TreeModel::iterator iterrow = selection->get_selected();
736 Gtk::TreeModel::Row row = *iterrow;
737 Tile *t = row[tiles_columns.tile];
738 t->getSmallTile()->setSecondColor(tile_smallmap_second_colorbutton->get_color());
739 fill_tile_smallmap(t);
744 void TileSetWindow::on_tile_third_color_changed()
746 Glib::RefPtr<Gtk::TreeSelection> selection = tiles_treeview->get_selection();
747 Gtk::TreeModel::iterator iterrow = selection->get_selected();
751 Gtk::TreeModel::Row row = *iterrow;
752 Tile *t = row[tiles_columns.tile];
753 t->getSmallTile()->setThirdColor(tile_smallmap_third_colorbutton->get_color());
754 fill_tile_smallmap(t);
759 void TileSetWindow::fill_colours(Tile *tile)
762 switch (tile->getSmallTile()->getPattern())
764 case SmallTile::SOLID:
765 tile_smallmap_second_colorbutton->set_sensitive(false);
766 tile_smallmap_third_colorbutton->set_sensitive(false);
767 tile_smallmap_first_colorbutton->set_color(tile->getSmallTile()->getColor());
769 case SmallTile::STIPPLED: case SmallTile::SUNKEN:
770 tile_smallmap_second_colorbutton->set_sensitive(true);
771 tile_smallmap_third_colorbutton->set_sensitive(false);
772 tile_smallmap_first_colorbutton->set_color(tile->getSmallTile()->getColor());
773 tile_smallmap_second_colorbutton->set_color(tile->getSmallTile()->getSecondColor());
775 case SmallTile::RANDOMIZED: case SmallTile::TABLECLOTH: case SmallTile::DIAGONAL: case SmallTile::CROSSHATCH: case SmallTile::SUNKEN_STRIPED:
776 tile_smallmap_second_colorbutton->set_sensitive(true);
777 tile_smallmap_third_colorbutton->set_sensitive(true);
778 tile_smallmap_first_colorbutton->set_color(tile->getSmallTile()->getColor());
779 tile_smallmap_second_colorbutton->set_color(tile->getSmallTile()->getSecondColor());
780 tile_smallmap_third_colorbutton->set_color(tile->getSmallTile()->getThirdColor());
785 void TileSetWindow::on_tile_pattern_changed()
787 Glib::RefPtr<Gtk::TreeSelection> selection = tiles_treeview->get_selection();
788 Gtk::TreeModel::iterator iterrow = selection->get_selected();
792 Gtk::TreeModel::Row row = *iterrow;
793 Tile *t = row[tiles_columns.tile];
794 int idx = tile_smallmap_pattern_combobox->get_active_row_number();
795 SmallTile::Pattern pattern = SmallTile::Pattern(idx);
796 t->getSmallTile()->setPattern(pattern);
798 fill_tile_smallmap(t);
803 void TileSetWindow::on_tile_type_changed()
805 int idx = tile_type_combobox->get_active_row_number();
806 Glib::RefPtr<Gtk::TreeSelection> selection = tiles_treeview->get_selection();
807 Gtk::TreeModel::iterator iterrow = selection->get_selected();
811 Gtk::TreeModel::Row row = *iterrow;
812 Tile *t = row[tiles_columns.tile];
813 t->setTypeByIndex(idx);
818 void TileSetWindow::on_tile_name_changed()
820 Glib::RefPtr<Gtk::TreeSelection> selection = tiles_treeview->get_selection();
821 Gtk::TreeModel::iterator iterrow = selection->get_selected();
825 Gtk::TreeModel::Row row = *iterrow;
826 row[tiles_columns.name] = tile_name_entry->get_text();
827 Tile *t = row[tiles_columns.tile];
828 t->setName(tile_name_entry->get_text());
833 void TileSetWindow::fill_tile_smallmap(Tile *tile)
835 for (int i = 0; i < 32; i++)
837 for (int j = 0; j < 32; j++)
839 bool shadowed = false;
842 else if (j == 32 - 1)
844 OverviewMap::draw_terrain_tile (tile_smallmap_surface,
845 tile_smallmap_surface_gc,
846 tile->getSmallTile()->getPattern(),
847 tile->getSmallTile()->getColor(),
848 tile->getSmallTile()->getSecondColor(),
849 tile->getSmallTile()->getThirdColor(),
854 tile_smallmap_image->property_pixmap() = tile_smallmap_surface;
857 void TileSetWindow::on_add_tilestyleset_clicked()
860 Gtk::FileChooserDialog chooser(*window, _("Choose a Name"),
861 Gtk::FILE_CHOOSER_ACTION_OPEN);
862 Gtk::FileFilter sav_filter;
863 sav_filter.add_pattern("*.png");
864 chooser.set_filter(sav_filter);
865 chooser.set_current_folder(Glib::get_home_dir());
867 chooser.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
868 chooser.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
869 chooser.set_default_response(Gtk::RESPONSE_ACCEPT);
872 int res = chooser.run();
874 if (res == Gtk::RESPONSE_ACCEPT)
876 std::string filename = chooser.get_filename();
878 //add a new empty tile to the tileset
879 TileStyleSet *t = new TileStyleSet();
880 //add it to the treeview
881 Gtk::TreeIter i = tilestylesets_list->append();
883 (*i)[tilestylesets_columns.name] = t->getName();
884 (*i)[tilestylesets_columns.tilestyleset] = t;
886 Tile *tile = get_selected_tile ();
888 tilestylesets_treeview->set_cursor (Gtk::TreePath (String::ucompose("%1", tile->size() - 1)));
889 image_filechooser_button->set_filename(filename);
894 TileStyle * TileSetWindow::get_selected_tilestyle ()
896 Glib::RefPtr<Gtk::TreeSelection> selection = tilestyles_treeview->get_selection();
897 Gtk::TreeModel::iterator iterrow = selection->get_selected();
901 Gtk::TreeModel::Row row = *iterrow;
902 return row[tilestyles_columns.tilestyle];
907 TileStyleSet * TileSetWindow::get_selected_tilestyleset ()
909 Glib::RefPtr<Gtk::TreeSelection> selection = tilestylesets_treeview->get_selection();
910 Gtk::TreeModel::iterator iterrow = selection->get_selected();
914 Gtk::TreeModel::Row row = *iterrow;
915 return row[tilestylesets_columns.tilestyleset];
920 Tile * TileSetWindow::get_selected_tile ()
922 Glib::RefPtr<Gtk::TreeSelection> selection = tiles_treeview->get_selection();
923 Gtk::TreeModel::iterator iterrow = selection->get_selected();
927 Gtk::TreeModel::Row row = *iterrow;
928 return row[tiles_columns.tile];
933 void TileSetWindow::on_remove_tilestyleset_clicked()
935 //erase the selected row from the treeview
936 //remove the tile from the tileset
937 Glib::RefPtr<Gtk::TreeSelection> selection = tilestylesets_treeview->get_selection();
938 Gtk::TreeModel::iterator iterrow = selection->get_selected();
942 Tile *t = get_selected_tile();
943 Gtk::TreeModel::Row row = *iterrow;
944 TileStyleSet *s = row[tilestylesets_columns.tilestyleset];
945 tilestylesets_list->erase(iterrow);
947 for (std::list<TileStyleSet*>::iterator it = t->begin(); it != t->end(); it++)
959 void TileSetWindow::on_tilestyle_changed()
961 TileStyle *t = get_selected_tilestyle ();
964 t->setType(TileStyle::Type(tilestyle_combobox->get_active_row_number()));
965 int idx = t->getType();
966 tilestyle_standard_image->property_pixbuf() =
967 tilestyle_standard_images[idx]->to_pixbuf();
971 void TileSetWindow::on_image_chosen()
973 std::string selected_filename = image_filechooser_button->get_filename();
974 if (selected_filename.empty())
976 if (inhibit_image_change == true)
978 inhibit_image_change = false;
982 unsigned int height = get_image_height (selected_filename);
983 unsigned int width = get_image_width (selected_filename);
984 if ((width % height) != 0)
987 std::string file = File::get_basename(selected_filename);
989 if (selected_filename != d_tileset->getFile(file))
990 File::copy (selected_filename, d_tileset->getFile(file));
992 d_tileset->setTileSize(height);
994 on_remove_tilestyleset_clicked();
997 TileStyleSet *set = new TileStyleSet();
998 Gtk::TreeIter i = tilestylesets_list->append();
1000 set->setSubDir(d_tileset->getSubDir());
1001 (*i)[tilestylesets_columns.subdir] = set->getSubDir();
1004 set->setName(File::get_basename(selected_filename));
1005 (*i)[tilestylesets_columns.name] = set->getName();
1006 (*i)[tilestylesets_columns.tilestyleset] = set;
1007 Tile *tile = get_selected_tile ();
1008 tile->push_back(set);
1010 int no = width / height;
1011 for (int j = 0; j < no; j++)
1013 int id = d_tileset->getFreeTileStyleId();
1016 TileStyle *style = new TileStyle();
1018 style->setType(TileStyle::LONE);
1019 set->push_back(style);
1023 needs_saving = true;
1026 void TileSetWindow::on_refresh_clicked()
1028 TileStyleSet *set = get_selected_tilestyleset ();
1029 set->instantiateImages(d_tileset->getTileSize(), d_tileset->getFile(set->getName()));
1032 void TileSetWindow::on_preview_tile_activated()
1034 Tile *tile = get_selected_tile();
1037 TilePreviewDialog d(tile, d_tileset->getTileSize());
1042 void TileSetWindow::on_roads_picture_activated()
1044 ImageEditorDialog d(d_tileset->getFile(d_tileset->getRoadsFilename()),
1046 d.set_icon_from_file(File::getMiscFile("various/tileset_icon.png"));
1047 d.set_parent_window(*window);
1048 int response = d.run();
1049 if (response == Gtk::RESPONSE_ACCEPT)
1051 std::string filename = d.get_selected_filename();
1052 std::string name = File::get_basename(filename);
1053 File::copy(filename, d_tileset->getFile(name));
1054 d_tileset->setRoadsFilename(name);
1055 needs_saving = true;
1058 void TileSetWindow::on_bridges_picture_activated()
1060 ImageEditorDialog d(d_tileset->getFile(d_tileset->getBridgesFilename()),
1062 d.set_icon_from_file(File::getMiscFile("various/tileset_icon.png"));
1063 d.set_parent_window(*window);
1064 int response = d.run();
1065 if (response == Gtk::RESPONSE_ACCEPT)
1067 std::string filename = d.get_selected_filename();
1068 std::string name = File::get_basename(filename);
1069 File::copy(filename, d_tileset->getFile(name));
1070 d_tileset->setBridgesFilename(name);
1071 needs_saving = true;
1074 void TileSetWindow::on_fog_picture_activated()
1076 ImageEditorDialog d(d_tileset->getFile(d_tileset->getFogFilename()),
1078 d.set_icon_from_file(File::getMiscFile("various/tileset_icon.png"));
1079 d.set_parent_window(*window);
1080 int response = d.run();
1081 if (response == Gtk::RESPONSE_ACCEPT)
1083 std::string filename = d.get_selected_filename();
1084 std::string name = File::get_basename(filename);
1085 File::copy(filename, d_tileset->getFile(name));
1086 d_tileset->setFogFilename(name);
1087 needs_saving = true;
1090 void TileSetWindow::on_flags_picture_activated()
1092 TilesetFlagEditorDialog d(d_tileset);
1093 d.set_icon_from_file(File::getMiscFile("various/tileset_icon.png"));
1094 d.set_parent_window(*window);
1095 int response = d.run();
1096 if (response == Gtk::RESPONSE_ACCEPT)
1098 std::string filename= d.get_selected_filename();
1100 //copy the file, and set the image name
1101 std::string name = File::get_basename(filename);
1102 if (filename != d_tileset->getFile(name))
1103 File::copy(filename, d_tileset->getFile(name));
1105 d_tileset->setFlagsFilename(name);
1106 needs_saving = true;
1109 void TileSetWindow::on_army_unit_selector_activated()
1111 TilesetSelectorEditorDialog d(d_tileset);
1112 d.set_icon_from_file(File::getMiscFile("various/tileset_icon.png"));
1113 int response = d.run();
1114 if (response == Gtk::RESPONSE_ACCEPT)
1116 std::string small = d.get_small_selector_filename();
1117 std::string large = d.get_large_selector_filename();
1119 //copy the files, and set the image names
1120 std::string name = File::get_basename(small);
1121 if (small != d_tileset->getFile(name))
1122 File::copy(small, d_tileset->getFile(name));
1123 d_tileset->setSmallSelectorFilename(name);
1125 name = File::get_basename(large);
1126 if (large != d_tileset->getFile(name))
1127 File::copy(large, d_tileset->getFile(name));
1128 d_tileset->setLargeSelectorFilename(name);
1130 needs_saving = true;
1134 void TileSetWindow::on_explosion_picture_activated()
1136 TilesetExplosionPictureEditorDialog d(d_tileset);
1137 d.set_icon_from_file(File::getMiscFile("various/tileset_icon.png"));
1138 int response = d.run();
1139 if (response == Gtk::RESPONSE_ACCEPT)
1141 std::string filename = d.get_selected_filename();
1142 std::string name = File::get_basename(filename);
1143 std::string dest =d_tileset->getFile(name);
1144 if (filename != d_tileset->getFile(name))
1146 File::copy (filename, d_tileset->getFile(name));
1147 d_tileset->setExplosionFilename(name);
1149 needs_saving = true;
1153 void TileSetWindow::load_tileset(std::string filename)
1155 current_save_filename = filename;
1157 Tileset *tileset = Tileset::create(filename);
1158 if (tileset == NULL)
1161 msg = "The tileset could not be loaded.";
1162 Gtk::MessageDialog dialog(*window, msg);
1166 tiles_list->clear();
1169 d_tileset = tileset;
1171 d_tileset->setSubDir(File::get_basename(filename));
1172 d_tileset->instantiateImages();
1173 for (Tileset::iterator i = d_tileset->begin(); i != d_tileset->end(); ++i)
1175 Gtk::TreeIter l = tiles_list->append();
1176 (*l)[tiles_columns.name] = (*i)->getName();
1177 (*l)[tiles_columns.tile] = *i;
1179 if (d_tileset->size())
1180 tiles_treeview->set_cursor (Gtk::TreePath ("0"));
1182 update_tileset_buttons();
1183 update_tilestyleset_buttons();
1184 update_tileset_menuitems();
1185 update_tile_panel();
1186 update_tilestyleset_panel();
1187 update_tilestyle_panel();
1188 update_tile_preview_menuitem();