1 /*
2  * editabletileset.h
3  * Copyright 2018, Thorbjørn Lindeijer <bjorn@lindeijer.nl>
4  *
5  * This file is part of Tiled.
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the Free
9  * Software Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along with
18  * this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #pragma once
22 
23 #include "editableasset.h"
24 #include "tileset.h"
25 
26 namespace Tiled {
27 
28 class EditableTile;
29 class EditableWangSet;
30 class ScriptImage;
31 class TilesetDocument;
32 
33 class EditableTileset : public EditableAsset
34 {
35     Q_OBJECT
36 
37     Q_PROPERTY(QString name READ name WRITE setName)
38     Q_PROPERTY(QString image READ image WRITE setImage)
39     Q_PROPERTY(QList<QObject*> tiles READ tiles)
40     Q_PROPERTY(QList<QObject*> wangSets READ wangSets)
41     Q_PROPERTY(int tileCount READ tileCount)
42     Q_PROPERTY(int nextTileId READ nextTileId)
43     Q_PROPERTY(int tileWidth READ tileWidth WRITE setTileWidth)
44     Q_PROPERTY(int tileHeight READ tileHeight WRITE setTileHeight)
45     Q_PROPERTY(QSize tileSize READ tileSize WRITE setTileSize)
46     Q_PROPERTY(int imageWidth READ imageWidth)
47     Q_PROPERTY(int imageHeight READ imageHeight)
48     Q_PROPERTY(QSize imageSize READ imageSize)
49     Q_PROPERTY(int tileSpacing READ tileSpacing)
50     Q_PROPERTY(int margin READ margin)
51     Q_PROPERTY(Alignment objectAlignment READ objectAlignment WRITE setObjectAlignment)
52     Q_PROPERTY(QPoint tileOffset READ tileOffset WRITE setTileOffset)
53     Q_PROPERTY(Orientation orientation READ orientation WRITE setOrientation)
54     Q_PROPERTY(QColor transparentColor READ transparentColor WRITE setTransparentColor)
55     Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor)
56     Q_PROPERTY(bool collection READ isCollection)
57     Q_PROPERTY(QList<QObject*> selectedTiles READ selectedTiles WRITE setSelectedTiles)
58 
59 public:
60     // Synchronized with Tiled::Alignment
61     enum Alignment {
62         Unspecified,
63         TopLeft,
64         Top,
65         TopRight,
66         Left,
67         Center,
68         Right,
69         BottomLeft,
70         Bottom,
71         BottomRight
72     };
73     Q_ENUM(Alignment)
74 
75     // Synchronized with Tileset::Orientation
76     enum Orientation {
77         Orthogonal,
78         Isometric,
79     };
80     Q_ENUM(Orientation)
81 
82     Q_INVOKABLE explicit EditableTileset(const QString &name = QString(),
83                                          QObject *parent = nullptr);
84     explicit EditableTileset(const Tileset *tileset, QObject *parent = nullptr);
85     explicit EditableTileset(TilesetDocument *tilesetDocument,
86                              QObject *parent = nullptr);
87     ~EditableTileset() override;
88 
89     bool isReadOnly() const final;
90 
91     const QString &name() const;
92     QString image() const;
93     int tileCount() const;
94     int nextTileId() const;
95     int tileWidth() const;
96     int tileHeight() const;
97     QSize tileSize() const;
98     int imageWidth() const;
99     int imageHeight() const;
100     QSize imageSize() const;
101     int tileSpacing() const;
102     int margin() const;
103     Alignment objectAlignment() const;
104     QPoint tileOffset() const;
105     Orientation orientation() const;
106     QColor transparentColor() const;
107     QColor backgroundColor() const;
108     bool isCollection() const;
109 
110     Q_INVOKABLE void loadFromImage(Tiled::ScriptImage *image,
111                                    const QString &source = QString());
112 
113     Q_INVOKABLE Tiled::EditableTile *tile(int id);
114     QList<QObject*> tiles();
115     QList<QObject*> wangSets();
116 
117     QList<QObject*> selectedTiles();
118     void setSelectedTiles(const QList<QObject*> &tiles);
119 
120     Q_INVOKABLE Tiled::EditableTile *addTile();
121     Q_INVOKABLE void removeTiles(const QList<QObject*> &tiles);
122 
123     Q_INVOKABLE Tiled::EditableWangSet *addWangSet(const QString &name, int type);
124     Q_INVOKABLE void removeWangSet(Tiled::EditableWangSet *wangSet);
125 
126     TilesetDocument *tilesetDocument() const;
127     Tileset *tileset() const;
128 
129 public slots:
130     void setName(const QString &name);
131     void setImage(const QString &imageFilePath);
132     void setTileWidth(int width);
133     void setTileHeight(int height);
134     void setTileSize(QSize size);
135     void setTileSize(int width, int height);
136     void setObjectAlignment(Alignment objectAlignment);
137     void setTileOffset(QPoint tileOffset);
138     void setOrientation(Orientation orientation);
139     void setTransparentColor(const QColor &color);
140     void setBackgroundColor(const QColor &color);
141 
142 private:
143     bool tilesFromEditables(const QList<QObject*> &editableTiles, QList<Tile *> &tiles);
144 
145     void attachTiles(const QList<Tile*> &tiles);
146     void detachTiles(const QList<Tile*> &tiles);
147     void detachWangSets(const QList<WangSet*> &wangSets);
148 
149     void tileObjectGroupChanged(Tile *tile);
150 
151     void wangSetAdded(Tileset *tileset, int index);
152     void wangSetRemoved(WangSet *wangSet);
153 
154     bool mReadOnly = false;
155     SharedTileset mTileset;
156 };
157 
158 
isReadOnly()159 inline bool EditableTileset::isReadOnly() const
160 {
161     return mReadOnly;
162 }
163 
name()164 inline const QString &EditableTileset::name() const
165 {
166     return tileset()->name();
167 }
168 
image()169 inline QString EditableTileset::image() const
170 {
171     return tileset()->imageSource().toString(QUrl::PreferLocalFile);
172 }
173 
tileCount()174 inline int EditableTileset::tileCount() const
175 {
176     return tileset()->tileCount();
177 }
178 
nextTileId()179 inline int EditableTileset::nextTileId() const
180 {
181     return tileset()->nextTileId();
182 }
183 
tileWidth()184 inline int EditableTileset::tileWidth() const
185 {
186     return tileset()->tileWidth();
187 }
188 
tileHeight()189 inline int EditableTileset::tileHeight() const
190 {
191     return tileset()->tileHeight();
192 }
193 
tileSize()194 inline QSize EditableTileset::tileSize() const
195 {
196     return tileset()->tileSize();
197 }
198 
imageWidth()199 inline int EditableTileset::imageWidth() const
200 {
201     return tileset()->imageWidth();
202 }
203 
imageHeight()204 inline int EditableTileset::imageHeight() const
205 {
206     return tileset()->imageHeight();
207 }
208 
imageSize()209 inline QSize EditableTileset::imageSize() const
210 {
211     return QSize(imageWidth(), imageHeight());
212 }
213 
tileSpacing()214 inline int EditableTileset::tileSpacing() const
215 {
216     return tileset()->tileSpacing();
217 }
218 
margin()219 inline int EditableTileset::margin() const
220 {
221     return tileset()->margin();
222 }
223 
objectAlignment()224 inline EditableTileset::Alignment EditableTileset::objectAlignment() const
225 {
226     return static_cast<Alignment>(tileset()->objectAlignment());
227 }
228 
tileOffset()229 inline QPoint EditableTileset::tileOffset() const
230 {
231     return tileset()->tileOffset();
232 }
233 
orientation()234 inline EditableTileset::Orientation EditableTileset::orientation() const
235 {
236     return static_cast<Orientation>(tileset()->orientation());
237 }
238 
transparentColor()239 inline QColor EditableTileset::transparentColor() const
240 {
241     return tileset()->transparentColor();
242 }
243 
backgroundColor()244 inline QColor EditableTileset::backgroundColor() const
245 {
246     return tileset()->backgroundColor();
247 }
248 
isCollection()249 inline bool EditableTileset::isCollection() const
250 {
251     return tileset()->isCollection();
252 }
253 
tileset()254 inline Tileset *EditableTileset::tileset() const
255 {
256     return static_cast<Tileset*>(object());
257 }
258 
setTileWidth(int width)259 inline void EditableTileset::setTileWidth(int width)
260 {
261     setTileSize(QSize(width, tileHeight()));
262 }
263 
setTileHeight(int height)264 inline void EditableTileset::setTileHeight(int height)
265 {
266     setTileSize(QSize(tileWidth(), height));
267 }
268 
setTileSize(int width,int height)269 inline void EditableTileset::setTileSize(int width, int height)
270 {
271     setTileSize(QSize(width, height));
272 }
273 
274 } // namespace Tiled
275 
276 Q_DECLARE_METATYPE(Tiled::EditableTileset*)
277