1 #ifndef NO_EDITOR
2 #include <boost/bind.hpp>
3 #include <boost/function.hpp>
4 
5 #include <iostream>
6 
7 #include "border_widget.hpp"
8 #include "button.hpp"
9 #include "editor.hpp"
10 #include "foreach.hpp"
11 #include "grid_widget.hpp"
12 #include "hex_object.hpp"
13 #include "hex_tile.hpp"
14 #include "hex_tileset_editor_dialog.hpp"
15 #include "image_widget.hpp"
16 #include "label.hpp"
17 #include "preview_tileset_widget.hpp"
18 #include "raster.hpp"
19 
20 namespace editor_dialogs
21 {
22 
23 namespace {
all_tileset_editor_dialogs()24 std::set<hex_tileset_editor_dialog*>& all_tileset_editor_dialogs() {
25 	static std::set<hex_tileset_editor_dialog*> all;
26 	return all;
27 }
28 }
29 
global_tile_update()30 void hex_tileset_editor_dialog::global_tile_update()
31 {
32 	foreach(hex_tileset_editor_dialog* d, all_tileset_editor_dialogs()) {
33 		d->init();
34 	}
35 }
36 
hex_tileset_editor_dialog(editor & e)37 hex_tileset_editor_dialog::hex_tileset_editor_dialog(editor& e)
38   : dialog(graphics::screen_width() - EDITOR_SIDEBAR_WIDTH, 160, EDITOR_SIDEBAR_WIDTH, 440), editor_(e), first_index_(-1)
39 {
40 	all_tileset_editor_dialogs().insert(this);
41 
42 	set_clear_bg_amount(255);
43 	if(hex::hex_object::get_editor_tiles().empty() == false) {
44 		category_ = hex::hex_object::get_editor_tiles().front()->get_editor_info().group;
45 	}
46 
47 	init();
48 }
49 
~hex_tileset_editor_dialog()50 hex_tileset_editor_dialog::~hex_tileset_editor_dialog()
51 {
52 	all_tileset_editor_dialogs().erase(this);
53 }
54 
init()55 void hex_tileset_editor_dialog::init()
56 {
57 	clear();
58 	using namespace gui;
59 	set_padding(20);
60 
61 	ASSERT_LOG(editor_.get_hex_tileset() >= 0
62 		&& size_t(editor_.get_hex_tileset()) < hex::hex_object::get_editor_tiles().size(),
63 		"Index of hex tileset out of bounds must be between 0 and "
64 		<< hex::hex_object::get_editor_tiles().size() << ", found " << editor_.get_hex_tileset());
65 
66 	button* category_button = new button(widget_ptr(new label(category_, graphics::color_white())), boost::bind(&hex_tileset_editor_dialog::show_category_menu, this));
67 	add_widget(widget_ptr(category_button), 10, 10);
68 
69 	grid_ptr grid(new gui::grid(3));
70 	int index = 0, first_index = -1;
71 	first_index_ = -1;
72 
73 	foreach(const hex::hex_tile_ptr& t, hex::hex_object::get_editor_tiles()) {
74 		if(t->get_editor_info().group == category_) {
75 			if(first_index_ == -1) {
76 				first_index_ = index;
77 			}
78 			image_widget* preview = new image_widget(t->get_editor_info().texture, 54, 54);
79 			preview->set_area(t->get_editor_info().image_rect);
80 			button_ptr tileset_button(new button(widget_ptr(preview), boost::bind(&hex_tileset_editor_dialog::set_tileset, this, index)));
81 			tileset_button->set_tooltip(t->name() + "/" + t->get_editor_info().name, 14);
82 			tileset_button->set_dim(58, 58);
83 			grid->add_col(gui::widget_ptr(new gui::border_widget(tileset_button, index == editor_.get_hex_tileset() ? graphics::color(255,255,255,255) : graphics::color(0,0,0,0))));
84 		}
85 		++index;
86 	}
87 
88 	grid->finish_row();
89 	add_widget(grid);
90 }
91 
select_category(const std::string & category)92 void hex_tileset_editor_dialog::select_category(const std::string& category)
93 {
94 	category_ = category;
95 	init();
96 
97 	if(first_index_ != -1) {
98 		set_tileset(first_index_);
99 	}
100 }
101 
close_context_menu(int index)102 void hex_tileset_editor_dialog::close_context_menu(int index)
103 {
104 	remove_widget(context_menu_);
105 	context_menu_.reset();
106 }
107 
show_category_menu()108 void hex_tileset_editor_dialog::show_category_menu()
109 {
110 	using namespace gui;
111 	gui::grid* grid = new gui::grid(2);
112 	grid->swallow_clicks();
113 	grid->set_show_background(true);
114 	grid->set_hpad(10);
115 	grid->allow_selection();
116 	grid->register_selection_callback(boost::bind(&hex_tileset_editor_dialog::close_context_menu, this, _1));
117 
118 	std::set<std::string> categories;
119 	foreach(const hex::hex_tile_ptr& t, hex::hex_object::get_hex_tiles()) {
120 		if(categories.count(t->get_editor_info().group)) {
121 			continue;
122 		}
123 
124 		categories.insert(t->get_editor_info().group);
125 
126 		image_widget* preview = new image_widget(t->get_editor_info().texture, 54, 54);
127 		preview->set_area(t->get_editor_info().image_rect);
128 		grid->add_col(widget_ptr(preview))
129 		     .add_col(widget_ptr(new label(t->get_editor_info().group, graphics::color_white())));
130 		grid->register_row_selection_callback(boost::bind(&hex_tileset_editor_dialog::select_category, this, t->get_editor_info().group));
131 	}
132 
133 	int mousex, mousey;
134 	SDL_GetMouseState(&mousex, &mousey);
135 	if(mousex + grid->width() > graphics::screen_width()) {
136 		mousex = graphics::screen_width() - grid->width();
137 	}
138 
139 	if(mousey + grid->height() > graphics::screen_height()) {
140 		mousey = graphics::screen_height() - grid->height();
141 	}
142 
143 	mousex -= x();
144 	mousey -= y();
145 
146 	remove_widget(context_menu_);
147 	context_menu_.reset(grid);
148 	add_widget(context_menu_, mousex, mousey);
149 }
150 
set_tileset(int index)151 void hex_tileset_editor_dialog::set_tileset(int index)
152 {
153 	if(editor_.get_hex_tileset() != index) {
154 		editor_.set_hex_tileset(index);
155 		init();
156 	}
157 }
158 
handle_event(const SDL_Event & event,bool claimed)159 bool hex_tileset_editor_dialog::handle_event(const SDL_Event& event, bool claimed)
160 {
161 	if(!claimed) {
162 		if(context_menu_) {
163 			gui::widget_ptr ptr = context_menu_;
164 			SDL_Event ev = event;
165 			normalize_event(&ev);
166 			return ptr->process_event(ev, claimed);
167 		}
168 
169 		switch(event.type) {
170 		case SDL_KEYDOWN:
171 			if(event.key.keysym.sym == SDLK_COMMA) {
172 				editor_.set_hex_tileset(editor_.get_hex_tileset()-1);
173 				while(hex::hex_object::get_hex_tiles()[editor_.get_hex_tileset()]->get_editor_info().group != category_) {
174 					editor_.set_hex_tileset(editor_.get_hex_tileset()-1);
175 				}
176 				set_tileset(editor_.get_hex_tileset());
177 				claimed = true;
178 			} else if(event.key.keysym.sym == SDLK_PERIOD) {
179 				editor_.set_hex_tileset(editor_.get_hex_tileset()+1);
180 				while(hex::hex_object::get_hex_tiles()[editor_.get_hex_tileset()]->get_editor_info().group != category_) {
181 					editor_.set_hex_tileset(editor_.get_hex_tileset()+1);
182 				}
183 				set_tileset(editor_.get_hex_tileset());
184 				claimed = true;
185 			}
186 			break;
187 		}
188 	}
189 
190 	return dialog::handle_event(event, claimed);
191 }
192 
193 }
194 
195 #endif // !NO_EDITOR
196