1 /*
2  * Copyright (C) 2014-2018 Christopho, Solarus - http://www.solarus-games.org
3  *
4  * Solarus Quest Editor 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  * Solarus Quest Editor 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 along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 #include "view_settings.h"
18 
19 namespace SolarusEditor {
20 
21 /**
22  * @brief Creates default view settings.
23  * @param parent The parent object or nullptr.
24  */
ViewSettings(QObject * parent)25 ViewSettings::ViewSettings(QObject* parent) :
26   QObject(parent),
27   zoom(1.0),
28   grid_visible(false),
29   grid_size(16, 16),
30   grid_style(GridStyle::DASHED),
31   grid_color(Qt::black),
32   min_layer(0),
33   max_layer(-1),
34   locked_layers(),
35   visible_layers(),
36   traversables_visible(true),
37   obstacles_visible(true),
38   visible_entity_types() {
39 
40   // Default settings.
41   const QList<EntityType>& entity_types = EntityTraits::get_values();
42   for (EntityType entity_type : entity_types) {
43     visible_entity_types.insert(entity_type);
44   }
45 }
46 
47 /**
48  * @brief Returns the current zoom factor.
49  * @return The zoom factor.
50  */
get_zoom() const51 double ViewSettings::get_zoom() const {
52   return zoom;
53 }
54 
55 /**
56  * @brief Sets the zoom factor.
57  *
58  * Emits zoom_changed() if there is a change.
59  *
60  * @param zoom The zoom factor to set.
61  */
set_zoom(double zoom)62 void ViewSettings::set_zoom(double zoom) {
63 
64   if (zoom == this->zoom) {
65     return;
66   }
67 
68   this->zoom = zoom;
69   emit zoom_changed(zoom);
70 }
71 
72 /**
73  * @brief Returns the current grid visibility setting.
74  * @return @c true if the grid is visible, @c false if it is hidden
75  * or not supported.
76  */
is_grid_visible() const77 bool ViewSettings::is_grid_visible() const {
78 
79   return grid_visible;
80 }
81 
82 /**
83  * @brief Shows or hides the grid.
84  *
85  * Emits grid_visibility_changed() if there is a change.
86  *
87  * @param grid_visible @c true to show the grid, @c false to hide it.
88  */
set_grid_visible(bool grid_visible)89 void ViewSettings::set_grid_visible(bool grid_visible) {
90 
91   if (grid_visible == this->grid_visible) {
92     return;
93   }
94 
95   this->grid_visible = grid_visible;
96   emit grid_visibility_changed(grid_visible);
97 }
98 
99 /**
100  * @brief Returns the current grid size setting.
101  * @return the current grid size.
102  */
get_grid_size() const103 QSize ViewSettings::get_grid_size() const {
104 
105   return grid_size;
106 }
107 
108 /**
109  * @brief Changes the current grid size.
110  *
111  * Emits grid_size_changed() if there is a change and if the grid is visible.
112  *
113  * @param size the new grid size.
114  */
set_grid_size(const QSize & size)115 void ViewSettings::set_grid_size(const QSize& size) {
116 
117   if (size == grid_size) {
118     return;
119   }
120 
121   grid_size = size;
122 
123   if (grid_visible) {
124     emit grid_size_changed(grid_size);
125   }
126 }
127 
128 /**
129  * @brief Returns the current grid style setting.
130  * @return the current grid style.
131  */
get_grid_style() const132 GridStyle ViewSettings::get_grid_style() const {
133 
134   return grid_style;
135 }
136 
137 /**
138  * @brief Changes the current grid style.
139  *
140  * Emits grid_style_changed() if there is a change and if the grid is visible.
141  *
142  * @param style the new grid style.
143  */
set_grid_style(GridStyle style)144 void ViewSettings::set_grid_style(GridStyle style) {
145 
146   if (style == grid_style) {
147     return;
148   }
149 
150   grid_style = style;
151 
152   if (grid_visible) {
153     emit grid_style_changed(grid_style);
154   }
155 }
156 
157 /**
158  * @brief Returns the current grid color setting.
159  * @return the current grid color.
160  */
get_grid_color() const161 QColor ViewSettings::get_grid_color() const {
162 
163   return grid_color;
164 }
165 
166 /**
167  * @brief Changes the current grid color.
168  *
169  * Emits grid_color_changed() if there is a change and if the grid is visible.
170  *
171  * @param color the new grid color.
172  */
set_grid_color(const QColor & color)173 void ViewSettings::set_grid_color(const QColor& color) {
174 
175   if (color == grid_color || !color.isValid()) {
176     return;
177   }
178 
179   grid_color = color;
180 
181   if (grid_visible) {
182     emit grid_color_changed(grid_color);
183   }
184 }
185 
186 /**
187  * @brief Returns the range of layers supported for visibility.
188  *
189  * Returns an empty range if layer visibility is not supported.
190  *
191  * @param[ou] min_layer The lowest layer.
192  * @param[ou] max_layer The highest layer.
193  */
get_layer_range(int & min_layer,int & max_layer) const194 void ViewSettings::get_layer_range(int& min_layer, int& max_layer) const {
195 
196   min_layer = this->min_layer;
197   max_layer = this->max_layer;
198 }
199 
200 /**
201  * @brief Sets the range of layers supported for visibility.
202  *
203  * Emits layer_range_changed().
204  * Calling this function resets all layers to visible.
205  *
206  * @param min_layer The lowest layer.
207  * @param max_layer The lowest layer.
208  */
set_layer_range(int min_layer,int max_layer)209 void ViewSettings::set_layer_range(int min_layer, int max_layer) {
210 
211   if (min_layer == this->min_layer && max_layer == this->max_layer) {
212     return;
213   }
214 
215   if (max_layer < min_layer) {
216     // Empty range: layer visibility is not supported.
217     min_layer = 0;
218     max_layer = -1;
219   }
220 
221   this->min_layer = min_layer;
222   this->max_layer = max_layer;
223 
224   emit layer_range_changed(min_layer, max_layer);
225 
226   locked_layers.clear();
227   visible_layers.clear();
228   show_all_layers();
229 }
230 
231 /**
232  * @brief Returns whether a layer is currently locked.
233  * @param layer The layer to test.
234  * @return @c true if this layer is locked, @c false if it is unlocked.
235  */
is_layer_locked(int layer) const236 bool ViewSettings::is_layer_locked(int layer) const {
237 
238   return locked_layers.find(layer) != locked_layers.end();
239 }
240 
241 /**
242  * @brief Locks or unlocks a layer.
243  *
244  * Emits layer_locking_changed() if there is a change.
245  *
246  * @param layer The layer to change.
247  * @param locked @c true to lock the layer, @c false to unlock it.
248  */
set_layer_locked(int layer,bool locked)249 void ViewSettings::set_layer_locked(int layer, bool locked) {
250 
251   Q_ASSERT(layer >= min_layer && layer <= max_layer);
252 
253   if (locked == is_layer_locked(layer)) {
254     return;
255   }
256 
257   if (locked) {
258     locked_layers.insert(layer);
259   }
260   else {
261     locked_layers.erase(layer);
262   }
263   emit layer_locking_changed(layer, locked);
264 }
265 
266 /**
267  * @brief Returns whether a layer is currently visible.
268  * @param layer The layer to test.
269  * @return @c true if this layer is visible, @c false if it is hidden.
270  */
is_layer_visible(int layer) const271 bool ViewSettings::is_layer_visible(int layer) const {
272 
273   return visible_layers.find(layer) != visible_layers.end();
274 }
275 
276 /**
277  * @brief Shows or hides a layer.
278  *
279  * Emits layer_visibility_changed() if there is a change.
280  *
281  * @param layer The layer to change.
282  * @param visible @c true to show the layer, @c false to hide it.
283  */
set_layer_visible(int layer,bool visible)284 void ViewSettings::set_layer_visible(int layer, bool visible) {
285 
286   Q_ASSERT(layer >= min_layer && layer <= max_layer);
287 
288   if (visible == is_layer_visible(layer)) {
289     return;
290   }
291 
292   if (visible) {
293     visible_layers.insert(layer);
294   }
295   else {
296     visible_layers.erase(layer);
297   }
298   emit layer_visibility_changed(layer, visible);
299 }
300 
301 /**
302  * @brief Shows all layers.
303  *
304  * Emits layers_visibility_changed() for each layers whose visibility changes.
305  */
show_all_layers()306 void ViewSettings::show_all_layers() {
307 
308   for (int i = min_layer; i <= max_layer; ++i) {
309     set_layer_visible(i, true);
310   }
311 }
312 
313 /**
314  * @brief Hides all layers.
315  *
316  * Emits layers_visibility_changed() for each layers whose visibility changes.
317  */
hide_all_layers()318 void ViewSettings::hide_all_layers() {
319 
320   for (int i = min_layer; i <= max_layer; ++i) {
321     set_layer_visible(i, false);
322   }
323 }
324 
325 /**
326  * @brief Returns whether traversable entities are currently shown.
327  * @return @c true if traversablers are shown.
328  */
are_traversables_visible() const329 bool ViewSettings::are_traversables_visible() const {
330   return traversables_visible;
331 }
332 
333 /**
334  * @brief Shows or hide traversable entities.
335  *
336  * Emits traversables_visbility_changed() if there is a change.
337  *
338  * @param traversable_visible @c true to show traversables.
339  */
set_traversables_visible(bool traversables_visible)340 void ViewSettings::set_traversables_visible(bool traversables_visible) {
341 
342   if (traversables_visible == this->traversables_visible) {
343     return;
344   }
345 
346   this->traversables_visible = traversables_visible;
347 
348   emit traversables_visibility_changed(traversables_visible);
349 }
350 
351 /**
352  * @brief Returns whether obstacle entities are currently shown.
353  * @return @c true if obstaclers are shown.
354  */
are_obstacles_visible() const355 bool ViewSettings::are_obstacles_visible() const {
356   return obstacles_visible;
357 }
358 
359 /**
360  * @brief Shows or hide obstacle entities.
361  *
362  * Emits obstacles_visbility_changed() if there is a change.
363  *
364  * @param obstacle_visible @c true to show obstacles.
365  */
set_obstacles_visible(bool obstacles_visible)366 void ViewSettings::set_obstacles_visible(bool obstacles_visible) {
367 
368   if (obstacles_visible == this->obstacles_visible) {
369     return;
370   }
371 
372   this->obstacles_visible = obstacles_visible;
373 
374   emit obstacles_visibility_changed(obstacles_visible);
375 }
376 /**
377  * @brief Returns whether a entity type is currently visible.
378  * @param entity_type The entity type to test.
379  * @return @c true if this entity type is visible, @c false if it is hidden.
380  */
is_entity_type_visible(EntityType entity_type) const381 bool ViewSettings::is_entity_type_visible(EntityType entity_type) const {
382 
383   return visible_entity_types.find(entity_type) != visible_entity_types.end();
384 }
385 
386 /**
387  * @brief Shows or hides an entity type.
388  *
389  * Emits entity_type_visibility_changed() if there is a change.
390  *
391  * @param entity_type The entity type to change.
392  * @param visible @c true to show the entity type, @c false to hide it.
393  */
set_entity_type_visible(EntityType entity_type,bool visible)394 void ViewSettings::set_entity_type_visible(EntityType entity_type, bool visible) {
395 
396   if (visible == is_entity_type_visible(entity_type)) {
397     return;
398   }
399 
400   if (visible) {
401     visible_entity_types.insert(entity_type);
402   }
403   else {
404     visible_entity_types.erase(entity_type);
405   }
406   emit entity_type_visibility_changed(entity_type, visible);
407 }
408 
409 /**
410  * @brief Shows all entity types.
411  *
412  * Emits entity_type_visibility_changed() for each type whose visibility changes.
413  */
show_all_entity_types()414 void ViewSettings::show_all_entity_types() {
415 
416   const QList<EntityType>& entity_types = EntityTraits::get_values();
417   for (EntityType entity_type : entity_types) {
418     set_entity_type_visible(entity_type, true);
419   }
420 }
421 
422 /**
423  * @brief Hides all entity types.
424  *
425  * Emits entity_type_visibility_changed() for each type whose visibility changes.
426  */
hide_all_entity_types()427 void ViewSettings::hide_all_entity_types() {
428 
429   const QList<EntityType>& entity_types = EntityTraits::get_values();
430   for (EntityType entity_type : entity_types) {
431     set_entity_type_visible(entity_type, false);
432   }
433 }
434 
435 }
436