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
25ObjectSettings::ObjectSettings(const std::string& name) :
26 m_name(name),
27 m_options()
28{
29}
30
31void
32ObjectSettings::add_option(std::unique_ptr<ObjectOption> option)
33{
34 m_options.push_back(std::move(option));
35}
36
37void
38ObjectSettings::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
44void
45ObjectSettings::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
53void
54ObjectSettings::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
62void
63ObjectSettings::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
71void
72ObjectSettings::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
80void
81ObjectSettings::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
89void
90ObjectSettings::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
98void
99ObjectSettings::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
106void
107ObjectSettings::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
118void
119ObjectSettings::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
130void
131ObjectSettings::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
141void
142ObjectSettings::add_remove()
143{
144 add_option(std::make_unique<RemoveObjectOption>());
145}
146
147void
148ObjectSettings::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
154void
155ObjectSettings::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
163void
164ObjectSettings::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
173void
174ObjectSettings::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
181void
182ObjectSettings::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
191void
192ObjectSettings::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
202void
203ObjectSettings::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
209void
210ObjectSettings::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
216void
217ObjectSettings::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
231void
232ObjectSettings::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
239void
240ObjectSettings::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
248void
249ObjectSettings::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
257void
258ObjectSettings::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
266void
267ObjectSettings::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
275void
276ObjectSettings::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
282void
283ObjectSettings::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
288void
289ObjectSettings::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
320void
321ObjectSettings::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