1 /*
2  * tile.h
3  * Copyright 2008-2014, Thorbjørn Lindeijer <thorbjorn@lindeijer.nl>
4  * Copyright 2009, Edward Hutchins <eah1@yahoo.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 "tiled.h"
34 
35 #include <QPixmap>
36 #include <QSharedPointer>
37 #include <QUrl>
38 
39 #include <memory>
40 
41 namespace Tiled {
42 
43 class ObjectGroup;
44 class Tileset;
45 
46 /**
47  * A single frame of an animated tile.
48  */
49 struct Frame
50 {
51     bool operator == (const Frame &frame) const
52     {
53         return tileId == frame.tileId &&
54                 duration == frame.duration;
55     }
56 
57     int tileId;
58     int duration;
59 };
60 
61 class TILEDSHARED_EXPORT Tile : public Object
62 {
63 public:
64     Tile(int id, Tileset *tileset);
65     Tile(const QPixmap &image, int id, Tileset *tileset);
66 
67     ~Tile();
68 
69     int id() const;
70 
71     Tileset *tileset() const;
72     QSharedPointer<Tileset> sharedTileset() const;
73 
74     const QPixmap &image() const;
75     void setImage(const QPixmap &image);
76 
77     const Tile *currentFrameTile() const;
78 
79     const QUrl &imageSource() const;
80     void setImageSource(const QUrl &imageSource);
81 
82     int width() const;
83     int height() const;
84     QSize size() const;
85 
86     QPoint offset() const;
87 
88     const QString &type() const;
89     void setType(const QString &type);
90 
91     qreal probability() const;
92     void setProbability(qreal probability);
93 
94     ObjectGroup *objectGroup() const;
95     void setObjectGroup(std::unique_ptr<ObjectGroup> objectGroup);
96     void swapObjectGroup(std::unique_ptr<ObjectGroup> &objectGroup);
97 
98     const QVector<Frame> &frames() const;
99     void setFrames(const QVector<Frame> &frames);
100     bool isAnimated() const;
101     int currentFrameIndex() const;
102     bool resetAnimation();
103     bool advanceAnimation(int ms);
104 
105     LoadingStatus imageStatus() const;
106     void setImageStatus(LoadingStatus status);
107 
108     Tile *clone(Tileset *tileset) const;
109 
110 private:
111     int mId;
112     Tileset *mTileset;
113     QPixmap mImage;
114     QUrl mImageSource;
115     LoadingStatus mImageStatus;
116     QString mType;
117     qreal mProbability;
118     std::unique_ptr<ObjectGroup> mObjectGroup;
119 
120     QVector<Frame> mFrames;
121     int mCurrentFrameIndex;
122     int mUnusedTime;
123 
124     friend class Tileset; // To allow changing the tile id
125 };
126 
127 /**
128  * Returns ID of this tile within its tileset.
129  */
id()130 inline int Tile::id() const
131 {
132     return mId;
133 }
134 
135 /**
136  * Returns the tileset that this tile is part of.
137  */
tileset()138 inline Tileset *Tile::tileset() const
139 {
140     return mTileset;
141 }
142 
143 /**
144  * Returns the image of this tile.
145  */
image()146 inline const QPixmap &Tile::image() const
147 {
148     return mImage;
149 }
150 
151 /**
152  * Sets the image of this tile.
153  */
setImage(const QPixmap & image)154 inline void Tile::setImage(const QPixmap &image)
155 {
156     mImage = image;
157     mImageStatus = image.isNull() ? LoadingError : LoadingReady;
158 }
159 
160 /**
161  * Returns the URL of the external image that represents this tile.
162  * When this tile doesn't refer to an external image, an empty URL is
163  * returned.
164  */
imageSource()165 inline const QUrl &Tile::imageSource() const
166 {
167     return mImageSource;
168 }
169 
setImageSource(const QUrl & imageSource)170 inline void Tile::setImageSource(const QUrl &imageSource)
171 {
172     mImageSource = imageSource;
173 }
174 
175 /**
176  * Returns the width of this tile.
177  */
width()178 inline int Tile::width() const
179 {
180     return mImage.width();
181 }
182 
183 /**
184  * Returns the height of this tile.
185  */
height()186 inline int Tile::height() const
187 {
188     return mImage.height();
189 }
190 
191 /**
192  * Returns the size of this tile.
193  */
size()194 inline QSize Tile::size() const
195 {
196     return mImage.size();
197 }
198 
199 /**
200  * Returns the type of this tile. Tile objects that do not have a type
201  * explicitly set on them are assumed to be of the type returned by this
202  * function.
203  */
type()204 inline const QString &Tile::type() const
205 {
206     return mType;
207 }
208 
209 /**
210  * Sets the type of this tile.
211  * \sa type()
212  */
setType(const QString & type)213 inline void Tile::setType(const QString &type)
214 {
215     mType = type;
216 }
217 
218 /**
219  * Returns the relative probability of this tile appearing while painting.
220  */
probability()221 inline qreal Tile::probability() const
222 {
223     return mProbability;
224 }
225 
226 /**
227  * Set the relative probability of this tile appearing while painting.
228  */
setProbability(qreal probability)229 inline void Tile::setProbability(qreal probability)
230 {
231     mProbability = probability;
232 }
233 
234 /**
235  * @return The group of objects associated with this tile. This is generally
236  *         expected to be used for editing collision shapes.
237  */
objectGroup()238 inline ObjectGroup *Tile::objectGroup() const
239 {
240     return mObjectGroup.get();
241 }
242 
frames()243 inline const QVector<Frame> &Tile::frames() const
244 {
245     return mFrames;
246 }
247 
isAnimated()248 inline bool Tile::isAnimated() const
249 {
250     return !mFrames.isEmpty();
251 }
252 
currentFrameIndex()253 inline int Tile::currentFrameIndex() const
254 {
255     return mCurrentFrameIndex;
256 }
257 
258 /**
259  * Returns the loading status of the image referenced by this tile.
260  */
imageStatus()261 inline LoadingStatus Tile::imageStatus() const
262 {
263     return mImageStatus;
264 }
265 
setImageStatus(LoadingStatus status)266 inline void Tile::setImageStatus(LoadingStatus status)
267 {
268     mImageStatus = status;
269 }
270 
271 } // namespace Tiled
272 
273 Q_DECLARE_METATYPE(Tiled::Tile*)
274