1 /*
2 * editablewangset.cpp
3 * Copyright 2019, Your Name <your.name@domain>
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 #include "editablewangset.h"
22
23 #include "changetilewangid.h"
24 #include "changewangsetdata.h"
25 #include "editablemanager.h"
26 #include "editabletile.h"
27 #include "editabletileset.h"
28 #include "scriptmanager.h"
29
30 #include <QCoreApplication>
31 #include <QJSEngine>
32
33 namespace Tiled {
34
EditableWangSet(EditableTileset * tileset,WangSet * wangSet,QObject * parent)35 EditableWangSet::EditableWangSet(EditableTileset *tileset,
36 WangSet *wangSet,
37 QObject *parent)
38 : EditableObject(tileset, wangSet, parent)
39 {
40
41 }
42
~EditableWangSet()43 EditableWangSet::~EditableWangSet()
44 {
45 EditableManager::instance().mEditableWangSets.remove(wangSet());
46 }
47
imageTile() const48 EditableTile *EditableWangSet::imageTile() const
49 {
50 return EditableManager::instance().editableTile(tileset(), wangSet()->imageTile());
51 }
52
tileset() const53 EditableTileset *EditableWangSet::tileset() const
54 {
55 return static_cast<EditableTileset*>(asset());
56 }
57
wangId(EditableTile * editableTile)58 QJSValue EditableWangSet::wangId(EditableTile *editableTile)
59 {
60 if (!editableTile) {
61 ScriptManager::instance().throwNullArgError(0);
62 return {};
63 }
64
65 QJSEngine *engine = ScriptManager::instance().engine();
66 WangId wangId = wangSet()->wangIdOfTile(editableTile->tile());
67
68 QJSValue wangIdArray = engine->newArray(WangId::NumIndexes);
69 for (quint32 i = 0; i < WangId::NumIndexes; ++i)
70 wangIdArray.setProperty(i, wangId.indexColor(i));
71
72 return wangIdArray;
73 }
74
setWangId(EditableTile * editableTile,QJSValue value)75 void EditableWangSet::setWangId(EditableTile *editableTile, QJSValue value)
76 {
77 if (!editableTile) {
78 ScriptManager::instance().throwNullArgError(0);
79 return;
80 }
81
82 const int length = value.property(QStringLiteral("length")).toInt();
83 if (!value.isArray() || length != WangId::NumIndexes) {
84 ScriptManager::instance().throwError(QCoreApplication::translate("Script Errors", "Wang ID must be an array of length 8"));
85 return;
86 }
87
88 WangId wangId;
89
90 for (quint32 i = 0; i < WangId::NumIndexes; ++i) {
91 const unsigned color = value.property(i).toUInt();
92 wangId.setIndexColor(i, color);
93 }
94
95 if (!wangSet()->wangIdIsValid(wangId)) {
96 ScriptManager::instance().throwError(QCoreApplication::translate("Script Errors", "Invalid Wang ID"));
97 return;
98 }
99
100 if (auto doc = tilesetDocument())
101 asset()->push(new ChangeTileWangId(doc, wangSet(), editableTile->tile(), wangId));
102 else if (!checkReadOnly())
103 wangSet()->setWangId(editableTile->id(), wangId);
104 }
105
setName(const QString & name)106 void EditableWangSet::setName(const QString &name)
107 {
108 if (auto document = tilesetDocument())
109 asset()->push(new RenameWangSet(document, wangSet(), name));
110 else if (!checkReadOnly())
111 wangSet()->setName(name);
112 }
113
setType(EditableWangSet::Type type)114 void EditableWangSet::setType(EditableWangSet::Type type)
115 {
116 if (auto document = tilesetDocument()) {
117 asset()->push(new ChangeWangSetType(document, wangSet(),
118 static_cast<WangSet::Type>(type)));
119 } else if (!checkReadOnly()) {
120 wangSet()->setType(static_cast<WangSet::Type>(type));
121 }
122 }
123
setImageTile(EditableTile * imageTile)124 void EditableWangSet::setImageTile(EditableTile *imageTile)
125 {
126 if (imageTile && imageTile->tileset() != tileset()) {
127 ScriptManager::instance().throwError(QCoreApplication::translate("Script Errors", "Tile not from the same tileset"));
128 return;
129 }
130
131 int tileId = imageTile ? imageTile->id() : -1;
132
133 if (auto document = tilesetDocument())
134 asset()->push(new SetWangSetImage(document, wangSet(), tileId));
135 else if (!checkReadOnly())
136 wangSet()->setImageTileId(tileId);
137 }
138
setColorCount(int n)139 void EditableWangSet::setColorCount(int n)
140 {
141 if (auto document = tilesetDocument()) {
142 asset()->push(new ChangeWangSetColorCount(document, wangSet(), n));
143 } else if (!checkReadOnly()) {
144 ChangeTileWangId::applyChanges(wangSet(),
145 ChangeTileWangId::changesOnSetColorCount(wangSet(), n));
146 wangSet()->setColorCount(n);
147 }
148 }
149
detach()150 void EditableWangSet::detach()
151 {
152 Q_ASSERT(tileset());
153
154 auto &editableManager = EditableManager::instance();
155
156 editableManager.mEditableWangSets.remove(wangSet());
157 setAsset(nullptr);
158
159 mDetachedWangSet.reset(wangSet()->clone(nullptr));
160 setObject(mDetachedWangSet.get());
161 editableManager.mEditableWangSets.insert(wangSet(), this);
162 }
163
attach(EditableTileset * tileset)164 void EditableWangSet::attach(EditableTileset *tileset)
165 {
166 Q_ASSERT(!asset() && tileset);
167
168 setAsset(tileset);
169 mDetachedWangSet.release();
170 }
171
hold()172 void EditableWangSet::hold()
173 {
174 Q_ASSERT(!asset()); // if asset exists, it holds the object (possibly indirectly)
175 Q_ASSERT(!mDetachedWangSet); // can't already be holding the object
176
177 mDetachedWangSet.reset(wangSet());
178 }
179
release()180 void EditableWangSet::release()
181 {
182 Q_ASSERT(mDetachedWangSet.get() == wangSet());
183
184 mDetachedWangSet.release();
185 }
186
tilesetDocument() const187 TilesetDocument *EditableWangSet::tilesetDocument() const
188 {
189 return tileset() ? tileset()->tilesetDocument() : nullptr;
190 }
191
192 } // namespace Tiled
193
194 #include "moc_editablewangset.cpp"
195