1 /*
2 * layer.h
3 * Copyright 2008-2010, Thorbjørn Lindeijer <thorbjorn@lindeijer.nl>
4 * Copyright 2009, Jeff Bland <jeff@teamphobic.com>
5 *
6 * This file is part of libtiled.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
21 * EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #pragma once
31
32 #include "object.h"
33 #include "tileset.h"
34
35 #include <QPixmap>
36 #include <QRect>
37 #include <QSet>
38 #include <QString>
39 #include <QVector>
40
41 namespace Tiled {
42
43 class GroupLayer;
44 class Map;
45 class ImageLayer;
46 class ObjectGroup;
47 class TileLayer;
48
49 /**
50 * A map layer.
51 */
52 class TILEDSHARED_EXPORT Layer : public Object
53 {
54 public:
55 enum TypeFlag {
56 TileLayerType = 0x01,
57 ObjectGroupType = 0x02,
58 ImageLayerType = 0x04,
59 GroupLayerType = 0x08
60 };
61
62 enum { AnyLayerType = 0xFF };
63
64 /**
65 * Constructor.
66 */
67 Layer(TypeFlag type, const QString &name, int x, int y);
68
69 /**
70 * The layer ID can be used to unique identify this layer of the map. It
71 * stays the same regardless of whether the layer is moved or renamed.
72 */
id()73 int id() const { return mId; }
setId(int id)74 void setId(int id) { mId = id; }
75 void resetIds();
76
tintColor()77 const QColor &tintColor() const { return mTintColor; }
setTintColor(const QColor & tintColor)78 void setTintColor(const QColor &tintColor) { mTintColor = tintColor; }
79
80 /**
81 * Returns the type of this layer.
82 */
layerType()83 TypeFlag layerType() const { return mLayerType; }
84
85 /**
86 * Returns the name of this layer.
87 */
name()88 const QString &name() const { return mName; }
89
90 /**
91 * Sets the name of this layer.
92 */
setName(const QString & name)93 void setName(const QString &name) { mName = name; }
94
95 /**
96 * Returns the opacity of this layer.
97 */
opacity()98 qreal opacity() const { return mOpacity; }
99
100 /**
101 * Sets the opacity of this layer.
102 */
setOpacity(qreal opacity)103 void setOpacity(qreal opacity) { mOpacity = opacity; }
104
105 /**
106 * Returns the effective opacity of this layer
107 */
108 qreal effectiveOpacity() const;
109
110 /**
111 * Returns the effective tint color of this layer
112 */
113 QColor effectiveTintColor() const;
114
115 /**
116 * Returns the visibility of this layer.
117 */
isVisible()118 bool isVisible() const { return mVisible; }
119
120 /**
121 * Returns the lock status of current layer.
122 */
isLocked()123 bool isLocked() const { return mLocked; }
124
125 /**
126 * Returns the lock status of layer including parent layers.
127 */
128 bool isUnlocked() const;
129
130 bool isHidden() const;
131
132 /**
133 * Sets the visibility of this layer.
134 */
setVisible(bool visible)135 void setVisible(bool visible) { mVisible = visible; }
136
setLocked(bool locked)137 void setLocked(bool locked) { mLocked = locked; }
138
139 /**
140 * Returns the map this layer is part of.
141 */
map()142 Map *map() const { return mMap; }
143
144 /**
145 * Returns the parent layer, if any.
146 */
parentLayer()147 GroupLayer *parentLayer() const { return mParentLayer; }
148
149 bool isParentOrSelf(const Layer *candidate) const;
150 int depth() const;
151 int siblingIndex() const;
152 QList<Layer*> siblings() const;
153
154 /**
155 * Returns the x position of this layer (in tiles).
156 */
x()157 int x() const { return mX; }
158
159 /**
160 * Sets the x position of this layer (in tiles).
161 */
setX(int x)162 void setX(int x) { mX = x; }
163
164 /**
165 * Returns the y position of this layer (in tiles).
166 */
y()167 int y() const { return mY; }
168
169 /**
170 * Sets the y position of this layer (in tiles).
171 */
setY(int y)172 void setY(int y) { mY = y; }
173
174 /**
175 * Returns the position of this layer (in tiles).
176 */
position()177 QPoint position() const { return QPoint(mX, mY); }
178
179 /**
180 * Sets the position of this layer (in tiles).
181 */
setPosition(QPoint pos)182 void setPosition(QPoint pos) { setPosition(pos.x(), pos.y()); }
setPosition(int x,int y)183 void setPosition(int x, int y) { mX = x; mY = y; }
184
185 void setOffset(const QPointF &offset);
186 QPointF offset() const;
187 QPointF totalOffset() const;
188
189 void setParallaxFactor(const QPointF &factor);
190 QPointF parallaxFactor() const;
191 QPointF effectiveParallaxFactor() const;
192
193 bool canMergeDown() const;
194
195 virtual bool isEmpty() const = 0;
196
197 /**
198 * Computes and returns the set of tilesets used by this layer.
199 */
200 virtual QSet<SharedTileset> usedTilesets() const = 0;
201
202 /**
203 * Returns whether this layer is referencing the given tileset.
204 */
205 virtual bool referencesTileset(const Tileset *tileset) const = 0;
206
207 /**
208 * Replaces all references to tiles from \a oldTileset with tiles from
209 * \a newTileset.
210 */
211 virtual void replaceReferencesToTileset(Tileset *oldTileset,
212 Tileset *newTileset) = 0;
213
214 /**
215 * Returns whether this layer can merge together with the \a other layer.
216 */
217 virtual bool canMergeWith(const Layer *other) const = 0;
218
219 /**
220 * Returns a newly allocated layer that is the result of merging this layer
221 * with the \a other layer. Where relevant, the other layer is considered
222 * to be on top of this one.
223 *
224 * Should only be called when canMergeWith returns true.
225 */
226 virtual Layer *mergedWith(const Layer *other) const = 0;
227
228 /**
229 * Returns a duplicate of this layer. The caller is responsible for the
230 * ownership of this newly created layer.
231 */
232 virtual Layer *clone() const = 0;
233
234 // These functions allow checking whether this Layer is an instance of the
235 // given subclass without relying on a dynamic_cast.
isTileLayer()236 bool isTileLayer() const { return mLayerType == TileLayerType; }
isObjectGroup()237 bool isObjectGroup() const { return mLayerType == ObjectGroupType; }
isImageLayer()238 bool isImageLayer() const { return mLayerType == ImageLayerType; }
isGroupLayer()239 bool isGroupLayer() const { return mLayerType == GroupLayerType; }
240
241 // These actually return this layer cast to one of its subclasses.
242 TileLayer *asTileLayer();
243 ObjectGroup *asObjectGroup();
244 ImageLayer *asImageLayer();
245 GroupLayer *asGroupLayer();
246
247 protected:
248 /**
249 * Sets the map this layer is part of. Should only be called from the
250 * Map class.
251 */
setMap(Map * map)252 virtual void setMap(Map *map) { mMap = map; }
setParentLayer(GroupLayer * groupLayer)253 void setParentLayer(GroupLayer *groupLayer) { mParentLayer = groupLayer; }
254
255 Layer *initializeClone(Layer *clone) const;
256
257 QString mName;
258 int mId = 0;
259 TypeFlag mLayerType;
260 int mX = 0;
261 int mY = 0;
262 QPointF mOffset;
263 QPointF mParallaxFactor = { 1.0, 1.0 };
264 qreal mOpacity = 1.0;
265 QColor mTintColor;
266 bool mVisible = true;
267 Map *mMap = nullptr;
268 GroupLayer *mParentLayer = nullptr;
269 bool mLocked = false;
270
271 friend class Map;
272 friend class GroupLayer;
273 };
274
275
276 /**
277 * Sets the drawing offset in pixels of this layer.
278 */
setOffset(const QPointF & offset)279 inline void Layer::setOffset(const QPointF &offset)
280 {
281 mOffset = offset;
282 }
283
284 /**
285 * Returns the drawing offset in pixels of this layer.
286 */
offset()287 inline QPointF Layer::offset() const
288 {
289 return mOffset;
290 }
291
292 /**
293 * Sets the parallax factor of this layer.
294 */
setParallaxFactor(const QPointF & factor)295 inline void Layer::setParallaxFactor(const QPointF &factor)
296 {
297 mParallaxFactor = factor;
298 }
299
300 /**
301 * Returns the parallax factor of this layer.
302 */
parallaxFactor()303 inline QPointF Layer::parallaxFactor() const
304 {
305 return mParallaxFactor;
306 }
307
308
309 /**
310 * An iterator for iterating over the layers of a map, in the order in which
311 * they are drawn. When iterating forward, group layers are traversed after
312 * their children.
313 *
314 * Modifying the layer hierarchy while an iterator is active will lead to
315 * undefined results!
316 */
317 class TILEDSHARED_EXPORT LayerIterator
318 {
319 public:
320 LayerIterator(const Map *map, int layerTypes = Layer::AnyLayerType);
321 LayerIterator(Layer *start);
322
323 Layer *currentLayer() const;
324 int currentSiblingIndex() const;
325
326 bool hasNextSibling() const;
327 bool hasPreviousSibling() const;
328 bool hasParent() const;
329
330 Layer *next();
331 Layer *previous();
332
333 void toFront();
334 void toBack();
335
336 // Allow use as general iterator and in range-based for loops
337 bool operator==(const LayerIterator &other) const;
338 bool operator!=(const LayerIterator &other) const;
339 LayerIterator &operator++();
340 LayerIterator operator++(int);
341 Layer *operator*() const;
342 Layer *operator->() const;
343
344 private:
345 const Map *mMap;
346 Layer *mCurrentLayer;
347 int mSiblingIndex;
348 int mLayerTypes;
349 };
350
351
352 /**
353 * Iterate the given map, starting from the first layer.
354 */
LayerIterator(const Map * map,int layerTypes)355 inline LayerIterator::LayerIterator(const Map *map, int layerTypes)
356 : mMap(map)
357 , mCurrentLayer(nullptr)
358 , mSiblingIndex(-1)
359 , mLayerTypes(layerTypes)
360 {}
361
362 /**
363 * Iterate the layer's map, starting at the given \a layer.
364 */
LayerIterator(Layer * start)365 inline LayerIterator::LayerIterator(Layer *start)
366 : mMap(start ? start->map() : nullptr)
367 , mCurrentLayer(start)
368 , mSiblingIndex(start ? start->siblingIndex() : -1)
369 , mLayerTypes(Layer::AnyLayerType)
370 {}
371
currentLayer()372 inline Layer *LayerIterator::currentLayer() const
373 {
374 return mCurrentLayer;
375 }
376
currentSiblingIndex()377 inline int LayerIterator::currentSiblingIndex() const
378 {
379 return mSiblingIndex;
380 }
381
hasNextSibling()382 inline bool LayerIterator::hasNextSibling() const
383 {
384 if (!mCurrentLayer)
385 return false;
386
387 return mSiblingIndex + 1 < mCurrentLayer->siblings().size();
388 }
389
hasPreviousSibling()390 inline bool LayerIterator::hasPreviousSibling() const
391 {
392 return mSiblingIndex > 0;
393 }
394
hasParent()395 inline bool LayerIterator::hasParent() const
396 {
397 return mCurrentLayer && mCurrentLayer->parentLayer();
398 }
399
400 inline bool LayerIterator::operator!=(const LayerIterator &other) const
401 {
402 return !(*this == other);
403 }
404
405 inline LayerIterator &LayerIterator::operator++()
406 {
407 next();
408 return *this;
409 }
410
411 inline LayerIterator LayerIterator::operator++(int)
412 {
413 LayerIterator it = *this;
414 next();
415 return it;
416 }
417
418 inline Layer *LayerIterator::operator*() const
419 {
420 return mCurrentLayer;
421 }
422
423 inline Layer *LayerIterator::operator->() const
424 {
425 return mCurrentLayer;
426 }
427
428
429 TILEDSHARED_EXPORT int globalIndex(Layer *layer);
430 TILEDSHARED_EXPORT Layer *layerAtGlobalIndex(const Map *map, int index);
431
432 } // namespace Tiled
433
434 Q_DECLARE_METATYPE(Tiled::Layer*)
435