1
2 /*
3 * wangdock.cpp
4 * Copyright 2017, Benjamin Trotter <bdtrotte@ucsc.edu>
5 *
6 * This file is part of Tiled.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "wangdock.h"
23
24 #include "changeevents.h"
25 #include "changewangsetdata.h"
26 #include "documentmanager.h"
27 #include "wangcolormodel.h"
28 #include "wangcolorview.h"
29 #include "wangoverlay.h"
30 #include "wangsetmodel.h"
31 #include "wangsetview.h"
32 #include "wangtemplatemodel.h"
33 #include "wangtemplateview.h"
34 #include "map.h"
35 #include "mapdocument.h"
36 #include "tilesetdocument.h"
37 #include "tilesetdocumentsmodel.h"
38 #include "tilesetwangsetmodel.h"
39 #include "utils.h"
40
41 #include <QAction>
42 #include <QEvent>
43 #include <QBoxLayout>
44 #include <QPushButton>
45 #include <QSortFilterProxyModel>
46 #include <QSplitter>
47 #include <QTabWidget>
48 #include <QToolBar>
49 #include <QTreeView>
50 #include <QUndoStack>
51 #include <QToolButton>
52 #include <QMenu>
53 #include <QPainter>
54 #include <QScopedValueRollback>
55 #include <QStackedWidget>
56 #include <QLabel>
57
58 using namespace Tiled;
59
60 namespace Tiled {
61
62 class NoWangSetWidget : public QWidget
63 {
64 Q_OBJECT
65
66 public:
NoWangSetWidget(QWidget * parent=nullptr)67 explicit NoWangSetWidget(QWidget *parent = nullptr)
68 : QWidget(parent)
69 {
70 QLabel *label = new QLabel(this);
71 label->setWordWrap(true);
72 label->setText(tr("<p>No tileset with Terrain Sets available.</p>"
73 "<p>Open a tileset with a Terrain Set or set up a new Terrain Set to be able to use the Terrain Brush or the Terrain Fill Mode.</p>"));
74
75 QGridLayout *gridLayout = new QGridLayout(this);
76 gridLayout->addWidget(label, 0, 0, Qt::AlignTop);
77 }
78 };
79
firstWangSet(MapDocument * mapDocument)80 static WangSet *firstWangSet(MapDocument *mapDocument)
81 {
82 for (const SharedTileset &tileset : mapDocument->map()->tilesets())
83 if (tileset->wangSetCount() > 0)
84 return tileset->wangSet(0);
85
86 return nullptr;
87 }
88
firstWangSet(TilesetDocument * tilesetDocument)89 static WangSet *firstWangSet(TilesetDocument *tilesetDocument)
90 {
91 Tileset *tileset = tilesetDocument->tileset().data();
92 if (tileset->wangSetCount() > 0)
93 return tileset->wangSet(0);
94
95 return nullptr;
96 }
97
98 class HasChildrenFilterModel : public QSortFilterProxyModel
99 {
100 public:
HasChildrenFilterModel(QObject * parent=nullptr)101 explicit HasChildrenFilterModel(QObject *parent = nullptr)
102 : QSortFilterProxyModel(parent)
103 , mEnabled(true)
104 {
105 }
106
setEnabled(bool enabled)107 void setEnabled(bool enabled) { mEnabled = enabled; }
108
109 protected:
filterAcceptsRow(int sourceRow,const QModelIndex & sourceParent) const110 bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override
111 {
112 if (!mEnabled)
113 return true;
114 if (sourceParent.isValid())
115 return true;
116
117 const QAbstractItemModel *model = sourceModel();
118 const QModelIndex index = model->index(sourceRow, 0, sourceParent);
119 return index.isValid() && model->hasChildren(index);
120 }
121
122 bool mEnabled;
123 };
124
125 } // namespace Tiled
126
WangDock(QWidget * parent)127 WangDock::WangDock(QWidget *parent)
128 : QDockWidget(parent)
129 , mWangSetToolBar(new QToolBar(this))
130 , mWangColorToolBar(new QToolBar(this))
131 , mNewWangSetButton(new QToolButton(this))
132 , mNewWangSetMenu(new QMenu(this))
133 , mAddCornerWangSet(new QAction(this))
134 , mAddEdgeWangSet(new QAction(this))
135 , mAddMixedWangSet(new QAction(this))
136 , mDuplicateWangSet(new QAction(this))
137 , mRemoveWangSet(new QAction(this))
138 , mAddColor(new QAction(this))
139 , mRemoveColor(new QAction(this))
140 , mStack(new QStackedWidget)
141 , mTilesetDocumentFilterModel(new TilesetDocumentsFilterModel(this))
142 , mWangColorModel(nullptr)
143 , mWangColorFilterModel(new QSortFilterProxyModel(this))
144 , mWangSetModel(new WangSetModel(mTilesetDocumentFilterModel, this))
145 , mWangSetProxyModel(new HasChildrenFilterModel(this))
146 , mWangTemplateModel(new WangTemplateModel(nullptr, this))
147 {
148 setObjectName(QLatin1String("WangSetDock"));
149
150 mWangSetView = new WangSetView;
151 mWangSetView->setModel(mWangSetProxyModel);
152 connect(mWangSetView->selectionModel(), &QItemSelectionModel::currentRowChanged,
153 this, &WangDock::refreshCurrentWangSet);
154 connect(mWangSetView, &QAbstractItemView::pressed,
155 this, &WangDock::wangSetIndexPressed);
156
157 connect(mWangSetProxyModel, &QAbstractItemModel::rowsRemoved,
158 this, &WangDock::checkAnyWangSets);
159 connect(mWangSetProxyModel, &QAbstractItemModel::rowsInserted,
160 this, &WangDock::checkAnyWangSets);
161 connect(mWangSetProxyModel, &QAbstractItemModel::modelReset,
162 this, &WangDock::checkAnyWangSets);
163 connect(mWangSetProxyModel, &QAbstractItemModel::rowsInserted,
164 this, &WangDock::expandRows);
165
166 mNewWangSetMenu->addAction(mAddCornerWangSet);
167 mNewWangSetMenu->addAction(mAddEdgeWangSet);
168 mNewWangSetMenu->addAction(mAddMixedWangSet);
169
170 mNewWangSetButton->setPopupMode(QToolButton::InstantPopup);
171 mNewWangSetButton->setMenu(mNewWangSetMenu);
172 mNewWangSetButton->setIcon(QIcon(QStringLiteral(":/images/22/add.png")));
173
174 mAddCornerWangSet->setIcon(wangSetIcon(WangSet::Corner));
175 mAddEdgeWangSet->setIcon(wangSetIcon(WangSet::Edge));
176 mAddMixedWangSet->setIcon(wangSetIcon(WangSet::Mixed));
177
178 mDuplicateWangSet->setIcon(QIcon(QStringLiteral(":/images/16/stock-duplicate-16.png")));
179 mDuplicateWangSet->setEnabled(false);
180 mRemoveWangSet->setIcon(QIcon(QStringLiteral(":/images/22/remove.png")));
181 mRemoveWangSet->setEnabled(false);
182
183 mAddColor->setIcon(QIcon(QStringLiteral(":/images/22/add-edge.png")));
184 mAddColor->setEnabled(false);
185 mRemoveColor->setIcon(QIcon(QStringLiteral(":/images/22/remove.png")));
186 mRemoveColor->setEnabled(false);
187
188 Utils::setThemeIcon(mNewWangSetButton, "add");
189 Utils::setThemeIcon(mRemoveWangSet, "remove");
190 Utils::setThemeIcon(mAddColor, "add");
191 Utils::setThemeIcon(mRemoveColor, "remove");
192
193 mWangSetToolBar->setFloatable(false);
194 mWangSetToolBar->setMovable(false);
195 mWangSetToolBar->setIconSize(Utils::smallIconSize());
196
197 mWangSetToolBar->addWidget(mNewWangSetButton);
198 mWangSetToolBar->addAction(mDuplicateWangSet);
199 mWangSetToolBar->addAction(mRemoveWangSet);
200
201 connect(mAddCornerWangSet, &QAction::triggered, this, [this] { addWangSetRequested(WangSet::Corner); });
202 connect(mAddEdgeWangSet, &QAction::triggered, this, [this] { addWangSetRequested(WangSet::Edge); });
203 connect(mAddMixedWangSet, &QAction::triggered, this, [this] { addWangSetRequested(WangSet::Mixed); });
204 connect(mDuplicateWangSet, &QAction::triggered, this, &WangDock::duplicateWangSetRequested);
205 connect(mRemoveWangSet, &QAction::triggered, this, &WangDock::removeWangSetRequested);
206
207 mWangColorToolBar->setFloatable(false);
208 mWangColorToolBar->setMovable(false);
209 mWangColorToolBar->setIconSize(Utils::smallIconSize());
210
211 mWangColorToolBar->addAction(mAddColor);
212 mWangColorToolBar->addAction(mRemoveColor);
213
214 connect(mAddColor, &QAction::triggered,
215 this, &WangDock::addColor);
216 connect(mRemoveColor, &QAction::triggered,
217 this, &WangDock::removeColor);
218
219 mWangTemplateView = new WangTemplateView;
220 mWangTemplateView->setModel(mWangTemplateModel);
221
222 connect(mWangTemplateView->selectionModel(), &QItemSelectionModel::currentChanged,
223 this, &WangDock::refreshCurrentWangId);
224
225 mWangColorView = new WangColorView;
226 mWangColorView->setModel(mWangColorFilterModel);
227
228 connect(mWangColorView->selectionModel(), &QItemSelectionModel::currentRowChanged,
229 this, &WangDock::refreshCurrentWangColor);
230 connect(mWangColorView, &QAbstractItemView::pressed,
231 this, &WangDock::wangColorIndexPressed);
232
233 mEraseWangIdsButton = new QPushButton(this);
234 mEraseWangIdsButton->setIconSize(Utils::smallIconSize());
235 mEraseWangIdsButton->setIcon(QIcon(QLatin1String(":images/22/stock-tool-eraser.png")));
236 mEraseWangIdsButton->setCheckable(true);
237 mEraseWangIdsButton->setAutoExclusive(true);
238 mEraseWangIdsButton->setChecked(mCurrentWangId == 0);
239
240 connect(mEraseWangIdsButton, &QPushButton::clicked,
241 this, &WangDock::activateErase);
242
243 // WangSet layout
244
245 QHBoxLayout *wangSetHorizontal = new QHBoxLayout;
246 wangSetHorizontal->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::MinimumExpanding));
247 wangSetHorizontal->addWidget(mWangSetToolBar);
248
249 QWidget *wangSetWidget = new QWidget;
250 QVBoxLayout *wangSetVertical = new QVBoxLayout(wangSetWidget);
251 wangSetVertical->setContentsMargins(0, 0, 0, 0);
252 wangSetVertical->addWidget(mWangSetView);
253 wangSetVertical->addLayout(wangSetHorizontal);
254
255 // WangColor and templates layout
256
257 QHBoxLayout *colorViewHorizontal = new QHBoxLayout;
258 colorViewHorizontal->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::MinimumExpanding));
259 colorViewHorizontal->addWidget(mWangColorToolBar);
260
261 mWangColorWidget = new QWidget;
262 QVBoxLayout *colorViewVertical = new QVBoxLayout(mWangColorWidget);
263 colorViewVertical->setContentsMargins(0, 0, 0, 0);
264 colorViewVertical->addWidget(mWangColorView);
265 colorViewVertical->addLayout(colorViewHorizontal);
266
267 mTemplateAndColorView = new QTabWidget;
268 mTemplateAndColorView->setDocumentMode(true);
269 mTemplateAndColorView->addTab(mWangColorWidget, tr("Terrains"));
270 mTemplateAndColorView->addTab(mWangTemplateView, tr("Patterns"));
271
272 QHBoxLayout *templateAndColorHorizontal = new QHBoxLayout;
273 templateAndColorHorizontal->addWidget(mEraseWangIdsButton);
274 templateAndColorHorizontal->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::MinimumExpanding));
275
276 mTemplateAndColorWidget = new QWidget;
277 QVBoxLayout *templateAndColorVertical = new QVBoxLayout(mTemplateAndColorWidget);
278 templateAndColorVertical->setContentsMargins(0, 0, 0, 0);
279 templateAndColorVertical->addWidget(mTemplateAndColorView);
280 templateAndColorVertical->addLayout(templateAndColorHorizontal);
281
282 // Splitter combining the WangSet and WangColor views
283
284 QSplitter *wangViews = new QSplitter;
285 wangViews->setOrientation(Qt::Vertical);
286 wangViews->addWidget(wangSetWidget);
287 wangViews->addWidget(mTemplateAndColorWidget);
288 wangViews->setCollapsible(1, false);
289
290 // View stack for showing the "No Terrain Sets defined" widget
291
292 mStack->insertWidget(0, new NoWangSetWidget);
293 mStack->insertWidget(1, wangViews);
294 mStack->setCurrentIndex(1);
295
296 hideTemplateColorView();
297 setWidget(mStack);
298 retranslateUi();
299 }
300
~WangDock()301 WangDock::~WangDock()
302 {
303 }
304
setDocument(Document * document)305 void WangDock::setDocument(Document *document)
306 {
307 if (mDocument == document)
308 return;
309
310 if (auto tilesetDocument = qobject_cast<TilesetDocument*>(mDocument))
311 tilesetDocument->disconnect(this);
312
313 mDocument = document;
314 QScopedValueRollback<bool> initializing(mInitializing, true);
315
316 if (auto mapDocument = qobject_cast<MapDocument*>(document)) {
317 mTilesetDocumentFilterModel->setMapDocument(mapDocument);
318
319 mWangSetProxyModel->setEnabled(true);
320 mWangSetProxyModel->setSourceModel(mWangSetModel);
321 mWangSetView->expandAll();
322
323 setCurrentWangSet(firstWangSet(mapDocument));
324
325 setColorView();
326 mWangSetToolBar->setVisible(false);
327 mWangColorToolBar->setVisible(false);
328 mWangColorView->setReadOnly(true);
329
330 mTemplateAndColorView->setTabEnabled(1, false);
331 mTemplateAndColorView->tabBar()->hide();
332 } else if (auto tilesetDocument = qobject_cast<TilesetDocument*>(document)) {
333 TilesetWangSetModel *wangSetModel = tilesetDocument->wangSetModel();
334
335 mWangSetView->setTilesetDocument(tilesetDocument);
336 mWangSetProxyModel->setEnabled(false);
337 mWangSetProxyModel->setSourceModel(wangSetModel);
338
339 setCurrentWangSet(firstWangSet(tilesetDocument));
340
341 connect(wangSetModel, &TilesetWangSetModel::wangSetChanged,
342 mWangTemplateModel, &WangTemplateModel::wangSetChanged);
343 connect(wangSetModel, &TilesetWangSetModel::wangSetChanged,
344 this, &WangDock::wangSetChanged);
345
346 mWangSetToolBar->setVisible(true);
347 mWangColorToolBar->setVisible(true);
348 mWangColorView->setReadOnly(false);
349
350 mTemplateAndColorView->setTabEnabled(1, true);
351 mTemplateAndColorView->tabBar()->show();
352
353 /*
354 * Removing a WangSet usually changes the selected WangSet without the
355 * selection changing rows, so we can't rely on the currentRowChanged
356 * signal.
357 */
358 connect(wangSetModel, &TilesetWangSetModel::wangSetRemoved,
359 this, &WangDock::refreshCurrentWangSet);
360
361 connect(tilesetDocument, &Document::changed, this, &WangDock::documentChanged);
362
363 } else {
364 mWangSetProxyModel->setSourceModel(nullptr);
365 setCurrentWangSet(nullptr);
366 mWangSetToolBar->setVisible(false);
367 mWangColorToolBar->setVisible(false);
368 }
369 }
370
editWangSetName(WangSet * wangSet)371 void WangDock::editWangSetName(WangSet *wangSet)
372 {
373 const QModelIndex index = wangSetIndex(wangSet);
374
375 QItemSelectionModel *selectionModel = mWangSetView->selectionModel();
376 selectionModel->setCurrentIndex(index,
377 QItemSelectionModel::ClearAndSelect |
378 QItemSelectionModel::Rows);
379
380 mWangSetView->edit(index);
381 }
382
editWangColorName(int colorIndex)383 void WangDock::editWangColorName(int colorIndex)
384 {
385 const QModelIndex index = mWangColorModel->colorIndex(colorIndex);
386 if (!index.isValid())
387 return;
388
389 const QModelIndex viewIndex = static_cast<QAbstractProxyModel*>(mWangColorView->model())->mapFromSource(index);
390 if (!viewIndex.isValid())
391 return;
392
393 QItemSelectionModel *selectionModel = mWangColorView->selectionModel();
394 selectionModel->setCurrentIndex(viewIndex,
395 QItemSelectionModel::ClearAndSelect |
396 QItemSelectionModel::Rows);
397
398 mWangColorView->edit(viewIndex);
399 }
400
changeEvent(QEvent * event)401 void WangDock::changeEvent(QEvent *event)
402 {
403 QDockWidget::changeEvent(event);
404 switch (event->type()) {
405 case QEvent::LanguageChange:
406 retranslateUi();
407 break;
408 default:
409 break;
410 }
411 }
412
refreshCurrentWangSet()413 void WangDock::refreshCurrentWangSet()
414 {
415 QItemSelectionModel *selectionModel = mWangSetView->selectionModel();
416 WangSet *wangSet = mWangSetView->wangSetAt(selectionModel->currentIndex());
417 setCurrentWangSet(wangSet);
418 }
419
refreshCurrentWangId()420 void WangDock::refreshCurrentWangId()
421 {
422 QItemSelectionModel *selectionModel = mWangTemplateView->selectionModel();
423 WangId wangId = mWangTemplateModel->wangIdAt(selectionModel->currentIndex());
424
425 if (mCurrentWangId == wangId)
426 return;
427
428 mCurrentWangId = wangId;
429
430 mEraseWangIdsButton->setChecked(!mCurrentWangId);
431
432 emit currentWangIdChanged(mCurrentWangId);
433 }
434
refreshCurrentWangColor()435 void WangDock::refreshCurrentWangColor()
436 {
437 QItemSelectionModel *selectionModel = mWangColorView->selectionModel();
438 const auto currentIndex = selectionModel->currentIndex();
439 int color = 0;
440
441 if (currentIndex.isValid()) {
442 QModelIndex index = static_cast<QAbstractProxyModel*>(mWangColorView->model())->mapToSource(currentIndex);
443 color = mWangColorModel->colorAt(index);
444 }
445
446 mEraseWangIdsButton->setChecked(color == 0);
447 mRemoveColor->setEnabled(color != 0);
448 emit wangColorChanged(color);
449 }
450
wangColorIndexPressed(const QModelIndex & index)451 void WangDock::wangColorIndexPressed(const QModelIndex &index)
452 {
453 const int color = mWangColorModel->colorAt(index);
454 if (!color)
455 return;
456
457 WangColor *currentWangColor = mCurrentWangSet->colorAt(color).data();
458 mDocument->setCurrentObject(currentWangColor, mWangColorModel->tilesetDocument());
459
460 emit selectWangBrush();
461 }
462
documentChanged(const ChangeEvent & change)463 void WangDock::documentChanged(const ChangeEvent &change)
464 {
465 switch (change.type) {
466 case ChangeEvent::WangSetChanged:
467 if (static_cast<const WangSetChangeEvent&>(change).properties & WangSetChangeEvent::TypeProperty)
468 mWangTemplateModel->wangSetChanged();
469 break;
470 default:
471 break;
472 }
473 }
474
wangSetChanged()475 void WangDock::wangSetChanged()
476 {
477 mWangColorModel->resetModel();
478 mWangColorView->expandAll();
479
480 refreshCurrentWangColor();
481 refreshCurrentWangId();
482
483 updateAddColorStatus();
484 }
485
wangSetIndexPressed(const QModelIndex & index)486 void WangDock::wangSetIndexPressed(const QModelIndex &index)
487 {
488 if (WangSet *wangSet = mWangSetView->wangSetAt(index)) {
489 mDocument->setCurrentObject(wangSet,
490 mWangSetView->tilesetDocumentAt(index));
491 }
492 }
493
expandRows(const QModelIndex & parent,int first,int last)494 void WangDock::expandRows(const QModelIndex &parent, int first, int last)
495 {
496 if (parent.isValid())
497 return;
498
499 for (int row = first; row <= last; ++row)
500 mWangSetView->expand(mWangSetProxyModel->index(row, 0, parent));
501 }
502
checkAnyWangSets()503 void WangDock::checkAnyWangSets()
504 {
505 if (mDocument && mDocument->type() == Document::MapDocumentType) {
506 const int rows = mWangSetProxyModel->rowCount();
507 mStack->setCurrentIndex(rows > 0 ? 1 : 0);
508 }
509 refreshCurrentWangSet();
510 }
511
addColor()512 void WangDock::addColor()
513 {
514 Q_ASSERT(mCurrentWangSet);
515
516 if (TilesetDocument *tilesetDocument = qobject_cast<TilesetDocument*>(mDocument)) {
517 tilesetDocument->undoStack()->push(new ChangeWangSetColorCount(tilesetDocument,
518 mCurrentWangSet,
519 mCurrentWangSet->colorCount() + 1));
520 editWangColorName(mCurrentWangSet->colorCount());
521 }
522 }
523
removeColor()524 void WangDock::removeColor()
525 {
526 Q_ASSERT(mCurrentWangSet);
527
528 TilesetDocument *tilesetDocument = qobject_cast<TilesetDocument*>(mDocument);
529 if (!tilesetDocument)
530 return;
531
532 const QItemSelectionModel *selectionModel = mWangColorView->selectionModel();
533 const QModelIndex index = static_cast<QAbstractProxyModel*>(mWangColorView->model())->mapToSource(selectionModel->currentIndex());
534 const int color = mWangColorModel->colorAt(index);
535 tilesetDocument->undoStack()->push(new RemoveWangSetColor(tilesetDocument,
536 mCurrentWangSet,
537 color));
538 }
539
setCurrentWangSet(WangSet * wangSet)540 void WangDock::setCurrentWangSet(WangSet *wangSet)
541 {
542 if (mCurrentWangSet == wangSet)
543 return;
544
545 mWangColorModel = nullptr;
546 TilesetDocument *tilesetDocument = nullptr;
547
548 if (wangSet) {
549 auto sharedTileset = wangSet->tileset()->sharedPointer();
550 auto documentManager = DocumentManager::instance();
551
552 tilesetDocument = documentManager->findTilesetDocument(sharedTileset);
553 if (tilesetDocument)
554 mWangColorModel = tilesetDocument->wangColorModel(wangSet);
555
556 mWangColorView->setTileSize(sharedTileset->tileSize());
557 }
558
559 mCurrentWangSet = wangSet;
560
561 emit currentWangSetChanged(mCurrentWangSet);
562
563 mWangTemplateModel->setWangSet(wangSet);
564 mWangColorFilterModel->setSourceModel(mWangColorModel);
565 mWangColorView->expandAll();
566
567 mRemoveColor->setEnabled(false);
568
569 activateErase();
570
571 if (wangSet) {
572 mWangSetView->setCurrentIndex(wangSetIndex(wangSet));
573
574 if (!mWangTemplateView->isVisible() && !mWangColorView->isVisible())
575 setColorView();
576
577 if (wangSet->colorCount() > 0 && !mWangTemplateView->isVisible()) {
578 const QModelIndex index = mWangColorModel->colorIndex(1);
579 mWangColorView->setCurrentIndex(static_cast<QAbstractProxyModel*>(mWangColorView->model())->mapFromSource(index));
580 }
581
582 updateAddColorStatus();
583 } else {
584 mWangSetView->selectionModel()->clearCurrentIndex();
585 mWangSetView->selectionModel()->clearSelection();
586
587 hideTemplateColorView();
588
589 mAddColor->setEnabled(false);
590 }
591
592 if (wangSet && !mInitializing && tilesetDocument)
593 mDocument->setCurrentObject(wangSet, tilesetDocument);
594
595 mDuplicateWangSet->setEnabled(wangSet);
596 mRemoveWangSet->setEnabled(wangSet);
597 }
598
activateErase()599 void WangDock::activateErase()
600 {
601 mEraseWangIdsButton->setChecked(true);
602
603 mCurrentWangId = WangId();
604
605 mWangTemplateView->selectionModel()->clearCurrentIndex();
606 mWangTemplateView->selectionModel()->clearSelection();
607 mWangColorView->selectionModel()->clearCurrentIndex();
608 mWangColorView->selectionModel()->clearSelection();
609
610 emit wangColorChanged(0);
611 }
612
updateAddColorStatus()613 void WangDock::updateAddColorStatus()
614 {
615 mAddColor->setEnabled(mCurrentWangSet->colorCount() < WangId::MAX_COLOR_COUNT);
616 }
617
retranslateUi()618 void WangDock::retranslateUi()
619 {
620 setWindowTitle(tr("Terrain Sets"));
621
622 mEraseWangIdsButton->setText(tr("Erase Terrain"));
623 mNewWangSetButton->setToolTip(tr("Add Terrain Set"));
624 mAddCornerWangSet->setText(tr("New Corner Set"));
625 mAddEdgeWangSet->setText(tr("New Edge Set"));
626 mAddMixedWangSet->setText(tr("New Mixed Set"));
627 mDuplicateWangSet->setText(tr("Duplicate Terrain Set"));
628 mRemoveWangSet->setText(tr("Remove Terrain Set"));
629 mAddColor->setText(tr("Add Terrain"));
630 mRemoveColor->setText(tr("Remove Terrain"));
631
632 mTemplateAndColorView->setTabText(0, tr("Terrains"));
633 mTemplateAndColorView->setTabText(1, tr("Patterns"));
634 }
635
wangSetIndex(WangSet * wangSet) const636 QModelIndex WangDock::wangSetIndex(WangSet *wangSet) const
637 {
638 QModelIndex sourceIndex;
639
640 if (mDocument->type() == Document::MapDocumentType)
641 sourceIndex = mWangSetModel->index(wangSet);
642 else if (auto tilesetDocument = qobject_cast<TilesetDocument*>(mDocument))
643 sourceIndex = tilesetDocument->wangSetModel()->index(wangSet);
644
645 return mWangSetProxyModel->mapFromSource(sourceIndex);
646 }
647
onWangIdUsedChanged(WangId wangId)648 void WangDock::onWangIdUsedChanged(WangId wangId)
649 {
650 const QModelIndex index = mWangTemplateModel->wangIdIndex(wangId);
651
652 if (index.isValid())
653 mWangTemplateView->update(index);
654 }
655
onColorCaptured(int color)656 void WangDock::onColorCaptured(int color)
657 {
658 const QModelIndex index = mWangColorModel->colorIndex(color);
659
660 if (index.isValid()) {
661 mWangColorView->setCurrentIndex(static_cast<QAbstractProxyModel*>(mWangColorView->model())->mapFromSource(index));
662 } else {
663 mWangColorView->selectionModel()->clearCurrentIndex();
664 mWangColorView->selectionModel()->clearSelection();
665 }
666 }
667
onCurrentWangIdChanged(WangId wangId)668 void WangDock::onCurrentWangIdChanged(WangId wangId)
669 {
670 const QModelIndex index = mWangTemplateModel->wangIdIndex(wangId);
671 if (!index.isValid()) {
672 activateErase();
673 return;
674 }
675
676 QItemSelectionModel *selectionModel = mWangTemplateView->selectionModel();
677
678 //this emits current changed, and thus updates the wangId and such.
679 selectionModel->setCurrentIndex(index, QItemSelectionModel::SelectCurrent);
680 }
681
setColorView()682 void WangDock::setColorView()
683 {
684 mTemplateAndColorWidget->setVisible(true);
685 mTemplateAndColorView->setCurrentWidget(mWangColorWidget);
686 retranslateUi();
687 }
688
hideTemplateColorView()689 void WangDock::hideTemplateColorView()
690 {
691 mTemplateAndColorWidget->setVisible(false);
692 }
693
694 #include "wangdock.moc"
695 #include "moc_wangdock.cpp"
696