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