1 | // SuperTux |
2 | // Copyright (C) 2015 Hume2 <teratux.mail@gmail.com> |
3 | // |
4 | // This program is free software: you can redistribute it and/or modify |
5 | // it under the terms of the GNU General Public License as published by |
6 | // the Free Software Foundation, either version 3 of the License, or |
7 | // (at your option) any later version. |
8 | // |
9 | // This program is distributed in the hope that it will be useful, |
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | // GNU General Public License for more details. |
13 | // |
14 | // You should have received a copy of the GNU General Public License |
15 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | |
17 | #include "editor/object_settings.hpp" |
18 | |
19 | #include <assert.h> |
20 | #include <sexp/value.hpp> |
21 | |
22 | #include "util/gettext.hpp" |
23 | #include "video/color.hpp" |
24 | |
25 | ObjectSettings::ObjectSettings(const std::string& name) : |
26 | m_name(name), |
27 | m_options() |
28 | { |
29 | } |
30 | |
31 | void |
32 | ObjectSettings::add_option(std::unique_ptr<ObjectOption> option) |
33 | { |
34 | m_options.push_back(std::move(option)); |
35 | } |
36 | |
37 | void |
38 | ObjectSettings::add_badguy(const std::string& text, std::vector<std::string>* value_ptr, |
39 | const std::string& key, unsigned int flags) |
40 | { |
41 | add_option(std::make_unique<BadGuySelectObjectOption>(text, value_ptr, key, flags)); |
42 | } |
43 | |
44 | void |
45 | ObjectSettings::add_color(const std::string& text, Color* value_ptr, |
46 | const std::string& key, |
47 | boost::optional<Color> default_value, |
48 | unsigned int flags) |
49 | { |
50 | add_option(std::make_unique<ColorObjectOption>(text, value_ptr, key, default_value, true, flags)); |
51 | } |
52 | |
53 | void |
54 | ObjectSettings::add_rgba(const std::string& text, Color* value_ptr, |
55 | const std::string& key, |
56 | boost::optional<Color> default_value, |
57 | unsigned int flags) |
58 | { |
59 | add_option(std::make_unique<ColorObjectOption>(text, value_ptr, key, default_value, true, flags)); |
60 | } |
61 | |
62 | void |
63 | ObjectSettings::add_rgb(const std::string& text, Color* value_ptr, |
64 | const std::string& key, |
65 | boost::optional<Color> default_value, |
66 | unsigned int flags) |
67 | { |
68 | add_option(std::make_unique<ColorObjectOption>(text, value_ptr, key, default_value, false, flags)); |
69 | } |
70 | |
71 | void |
72 | ObjectSettings::add_bool(const std::string& text, bool* value_ptr, |
73 | const std::string& key, |
74 | boost::optional<bool> default_value, |
75 | unsigned int flags) |
76 | { |
77 | add_option(std::make_unique<BoolObjectOption>(text, value_ptr, key, default_value, flags)); |
78 | } |
79 | |
80 | void |
81 | ObjectSettings::add_float(const std::string& text, float* value_ptr, |
82 | const std::string& key, |
83 | boost::optional<float> default_value, |
84 | unsigned int flags) |
85 | { |
86 | add_option(std::make_unique<FloatObjectOption>(text, value_ptr, key, default_value, flags)); |
87 | } |
88 | |
89 | void |
90 | ObjectSettings::add_int(const std::string& text, int* value_ptr, |
91 | const std::string& key, |
92 | boost::optional<int> default_value, |
93 | unsigned int flags) |
94 | { |
95 | add_option(std::make_unique<IntObjectOption>(text, value_ptr, key, default_value, flags)); |
96 | } |
97 | |
98 | void |
99 | ObjectSettings::add_rectf(const std::string& text, Rectf* value_ptr, |
100 | const std::string& key, |
101 | unsigned int flags) |
102 | { |
103 | add_option(std::make_unique<RectfObjectOption>(text, value_ptr, key, flags)); |
104 | } |
105 | |
106 | void |
107 | ObjectSettings::add_direction(const std::string& text, Direction* value_ptr, |
108 | boost::optional<Direction> default_value, |
109 | const std::string& key, unsigned int flags) |
110 | { |
111 | add_enum(text, reinterpret_cast<int*>(value_ptr), |
112 | {_("auto" ), _("left" ), _("right" ), _("up" ), _("down" )}, |
113 | {"auto" , "left" , "right" , "up" , "down" }, |
114 | default_value ? static_cast<int>(*default_value) : boost::optional<int>(), |
115 | key, flags); |
116 | } |
117 | |
118 | void |
119 | ObjectSettings::add_worldmap_direction(const std::string& text, worldmap::Direction* value_ptr, |
120 | boost::optional<worldmap::Direction> default_value, |
121 | const std::string& key, unsigned int flags) |
122 | { |
123 | add_enum(text, reinterpret_cast<int*>(value_ptr), |
124 | {_("None" ), _("West" ), _("East" ), _("North" ), _("South" )}, |
125 | {"none" , "west" , "east" , "north" , "south" }, |
126 | default_value ? static_cast<int>(*default_value) : boost::optional<int>(), |
127 | key, flags); |
128 | } |
129 | |
130 | void |
131 | ObjectSettings::add_walk_mode(const std::string& text, WalkMode* value_ptr, |
132 | boost::optional<WalkMode> default_value, |
133 | const std::string& key, unsigned int flags) |
134 | { |
135 | add_option(std::make_unique<StringSelectObjectOption>( |
136 | text, reinterpret_cast<int*>(value_ptr), |
137 | std::vector<std::string>{_("One shot" ), _("Ping-pong" ), _("Circular" ), _("Unordered" )}, |
138 | boost::none, key, flags)); |
139 | } |
140 | |
141 | void |
142 | ObjectSettings::add_remove() |
143 | { |
144 | add_option(std::make_unique<RemoveObjectOption>()); |
145 | } |
146 | |
147 | void |
148 | ObjectSettings::add_script(const std::string& text, std::string* value_ptr, |
149 | const std::string& key, unsigned int flags) |
150 | { |
151 | add_option(std::make_unique<ScriptObjectOption>(text, value_ptr, key, flags)); |
152 | } |
153 | |
154 | void |
155 | ObjectSettings::add_text(const std::string& text, std::string* value_ptr, |
156 | const std::string& key, |
157 | boost::optional<std::string> default_value, |
158 | unsigned int flags) |
159 | { |
160 | add_option(std::make_unique<StringObjectOption>(text, value_ptr, key, default_value, flags)); |
161 | } |
162 | |
163 | void |
164 | ObjectSettings::add_translatable_text(const std::string& text, std::string* value_ptr, |
165 | const std::string& key, |
166 | boost::optional<std::string> default_value, |
167 | unsigned int flags) |
168 | { |
169 | add_option(std::make_unique<StringObjectOption>(text, value_ptr, key, default_value, |
170 | flags | OPTION_TRANSLATABLE)); |
171 | } |
172 | |
173 | void |
174 | ObjectSettings::add_string_select(const std::string& text, int* value_ptr, const std::vector<std::string>& select, |
175 | boost::optional<int> default_value, |
176 | const std::string& key, unsigned int flags) |
177 | { |
178 | add_option(std::make_unique<StringSelectObjectOption>(text, value_ptr, select, default_value, key, flags)); |
179 | } |
180 | |
181 | void |
182 | ObjectSettings::add_enum(const std::string& text, int* value_ptr, |
183 | const std::vector<std::string>& labels, |
184 | const std::vector<std::string>& symbols, |
185 | boost::optional<int> default_value, |
186 | const std::string& key, unsigned int flags) |
187 | { |
188 | add_option(std::make_unique<EnumObjectOption>(text, value_ptr, labels, symbols, default_value, key, flags)); |
189 | } |
190 | |
191 | void |
192 | ObjectSettings::add_file(const std::string& text, std::string* value_ptr, |
193 | const std::string& key, |
194 | boost::optional<std::string> default_value, |
195 | const std::vector<std::string>& filter, |
196 | const std::string& basedir, |
197 | unsigned int flags) |
198 | { |
199 | add_option(std::make_unique<FileObjectOption>(text, value_ptr, default_value, key, filter, basedir, flags)); |
200 | } |
201 | |
202 | void |
203 | ObjectSettings::add_tiles(const std::string& text, TileMap* value_ptr, const std::string& key, |
204 | unsigned int flags) |
205 | { |
206 | add_option(std::make_unique<TilesObjectOption>(text, value_ptr, key, flags)); |
207 | } |
208 | |
209 | void |
210 | ObjectSettings::add_path(const std::string& text, Path* path, const std::string& key, |
211 | unsigned int flags) |
212 | { |
213 | add_option(std::make_unique<PathObjectOption>(text, path, key, flags)); |
214 | } |
215 | |
216 | void |
217 | ObjectSettings::add_path_ref(const std::string& text, const std::string& path_ref, const std::string& key, |
218 | unsigned int flags) |
219 | { |
220 | add_option(std::make_unique<PathRefObjectOption>(text, path_ref, key, flags)); |
221 | |
222 | if (!path_ref.empty()) { |
223 | m_options.erase(std::remove_if(m_options.begin(), m_options.end(), |
224 | [](const std::unique_ptr<ObjectOption>& obj) { |
225 | return obj->get_key() == "x" || obj->get_key() == "y" ; |
226 | }), |
227 | m_options.end()); |
228 | } |
229 | } |
230 | |
231 | void |
232 | ObjectSettings::add_level(const std::string& text, std::string* value_ptr, const std::string& key, |
233 | const std::string& basedir, |
234 | unsigned int flags) |
235 | { |
236 | add_file(text, value_ptr, key, {}, {".stl" }, basedir, flags); |
237 | } |
238 | |
239 | void |
240 | ObjectSettings::add_sprite(const std::string& text, std::string* value_ptr, |
241 | const std::string& key, |
242 | boost::optional<std::string> default_value, |
243 | unsigned int flags) |
244 | { |
245 | add_file(text, value_ptr, key, std::move(default_value), {".jpg" , ".png" , ".sprite" }, {}, flags); |
246 | } |
247 | |
248 | void |
249 | ObjectSettings::add_surface(const std::string& text, std::string* value_ptr, |
250 | const std::string& key, |
251 | boost::optional<std::string> default_value, |
252 | unsigned int flags) |
253 | { |
254 | add_file(text, value_ptr, key, std::move(default_value), {".jpg" , ".png" , ".surface" }, {}, flags); |
255 | } |
256 | |
257 | void |
258 | ObjectSettings::add_sound(const std::string& text, std::string* value_ptr, |
259 | const std::string& key, |
260 | boost::optional<std::string> default_value, |
261 | unsigned int flags) |
262 | { |
263 | add_file(text, value_ptr, key, std::move(default_value), {".wav" , ".ogg" }, {}, flags); |
264 | } |
265 | |
266 | void |
267 | ObjectSettings::add_music(const std::string& text, std::string* value_ptr, |
268 | const std::string& key, |
269 | boost::optional<std::string> default_value, |
270 | unsigned int flags) |
271 | { |
272 | add_file(text, value_ptr, key, std::move(default_value), {".music" }, {}, flags); |
273 | } |
274 | |
275 | void |
276 | ObjectSettings::add_worldmap(const std::string& text, std::string* value_ptr, const std::string& key, |
277 | unsigned int flags) |
278 | { |
279 | add_file(text, value_ptr, key, {}, {".stwm" }, {}, flags); |
280 | } |
281 | |
282 | void |
283 | ObjectSettings::add_sexp(const std::string& text, const std::string& key, sexp::Value& value, unsigned int flags) |
284 | { |
285 | add_option(std::make_unique<SExpObjectOption>(text, key, value, flags)); |
286 | } |
287 | |
288 | void |
289 | ObjectSettings::reorder(const std::vector<std::string>& order) |
290 | { |
291 | std::vector<std::unique_ptr<ObjectOption> > new_options; |
292 | |
293 | // put all items not in 'order' into 'new_options' |
294 | for(auto& option : m_options) { |
295 | if (option) { |
296 | auto it = std::find(order.begin(), order.end(), option->get_key()); |
297 | if (it == order.end()) |
298 | { |
299 | new_options.push_back(std::move(option)); |
300 | } |
301 | } |
302 | } |
303 | |
304 | // put all other items in 'order' into 'new_options' in the order of 'order' |
305 | for(const auto& option_name : order) { |
306 | auto it = std::find_if(m_options.begin(), m_options.end(), |
307 | [option_name](const std::unique_ptr<ObjectOption>& option){ |
308 | return option && option->get_key() == option_name; |
309 | }); |
310 | if (it != m_options.end()) { |
311 | new_options.push_back(std::move(*it)); |
312 | } |
313 | } |
314 | |
315 | assert(m_options.size() == new_options.size()); |
316 | |
317 | m_options = std::move(new_options); |
318 | } |
319 | |
320 | void |
321 | ObjectSettings::remove(const std::string& key) |
322 | { |
323 | m_options.erase(std::remove_if(m_options.begin(), m_options.end(), |
324 | [key](const std::unique_ptr<ObjectOption>& option){ |
325 | return option->get_key() == key; |
326 | }), |
327 | m_options.end()); |
328 | } |
329 | |
330 | /* EOF */ |
331 | |