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