|
20 | 20 |
|
21 | 21 | #include "propertiesdock.h" |
22 | 22 |
|
| 23 | +#include "mapdocument.h" |
| 24 | +#include "mapobject.h" |
23 | 25 | #include "propertiesview.h" |
24 | 26 | #include "propertieswidget.h" |
| 27 | +#include "tilesetdocument.h" |
25 | 28 |
|
26 | 29 | #include <QKeyEvent> |
| 30 | +#include <QTabBar> |
| 31 | +#include <QVBoxLayout> |
27 | 32 |
|
28 | 33 | namespace Tiled { |
29 | 34 |
|
30 | 35 | PropertiesDock::PropertiesDock(QWidget *parent) |
31 | 36 | : QDockWidget(parent) |
| 37 | + , mTabBar(new QTabBar(this)) |
32 | 38 | , mPropertiesWidget(new PropertiesWidget(this)) |
33 | 39 | { |
34 | 40 | setObjectName(QLatin1String("propertiesDock")); |
35 | | - setWidget(mPropertiesWidget); |
| 41 | + |
| 42 | + mTabBar->setDocumentMode(true); |
| 43 | + mTabBar->setUsesScrollButtons(true); // defaults to false on macOS |
| 44 | + |
| 45 | + mTabBar->insertTab(MapTab, tr("Map")); |
| 46 | + mTabBar->insertTab(LayerTab, tr("Layer")); |
| 47 | + mTabBar->insertTab(MapObjectTab, tr("Object")); |
| 48 | + mTabBar->insertTab(TilesetTab, tr("Tileset")); |
| 49 | + mTabBar->insertTab(TileTab, tr("Tile")); |
| 50 | + mTabBar->insertTab(WangSetTab, tr("Terrain Set")); |
| 51 | + mTabBar->insertTab(WangColorTab, tr("Terrain")); |
| 52 | + |
| 53 | + auto widget = new QWidget(this); |
| 54 | + auto layout = new QVBoxLayout(widget); |
| 55 | + layout->setContentsMargins(0, 0, 0, 0); |
| 56 | + layout->setSpacing(0); |
| 57 | + layout->addWidget(mTabBar); |
| 58 | + layout->addWidget(mPropertiesWidget); |
| 59 | + |
| 60 | + setWidget(widget); |
| 61 | + |
| 62 | + connect(mTabBar, &QTabBar::currentChanged, |
| 63 | + this, &PropertiesDock::tabChanged); |
36 | 64 |
|
37 | 65 | connect(mPropertiesWidget, &PropertiesWidget::bringToFront, |
38 | 66 | this, &PropertiesDock::bringToFront); |
39 | 67 |
|
| 68 | + updateTabs(); |
40 | 69 | retranslateUi(); |
41 | 70 | } |
42 | 71 |
|
43 | 72 | void PropertiesDock::setDocument(Document *document) |
44 | 73 | { |
| 74 | + if (mDocument == document) |
| 75 | + return; |
| 76 | + |
| 77 | + if (mDocument) |
| 78 | + mDocument->disconnect(this); |
| 79 | + |
| 80 | + if (document) { |
| 81 | + connect(document, &Document::currentObjectChanged, |
| 82 | + this, &PropertiesDock::updateTabs); |
| 83 | + |
| 84 | + switch (document->type()) { |
| 85 | + case Document::MapDocumentType: { |
| 86 | + auto mapDocument = static_cast<MapDocument *>(document); |
| 87 | + connect(mapDocument, &MapDocument::selectedLayersChanged, |
| 88 | + this, &PropertiesDock::updateTabs); |
| 89 | + connect(mapDocument, &MapDocument::selectedObjectsChanged, |
| 90 | + this, &PropertiesDock::updateTabs); |
| 91 | + break; |
| 92 | + } |
| 93 | + case Document::TilesetDocumentType: { |
| 94 | + auto tilesetDocument = static_cast<TilesetDocument *>(document); |
| 95 | + connect(tilesetDocument, &TilesetDocument::selectedTilesChanged, |
| 96 | + this, &PropertiesDock::updateTabs); |
| 97 | + break; |
| 98 | + } |
| 99 | + case Document::WorldDocumentType: |
| 100 | + case Document::ProjectDocumentType: |
| 101 | + break; |
| 102 | + } |
| 103 | + } |
| 104 | + |
| 105 | + mDocument = document; |
45 | 106 | mPropertiesWidget->setDocument(document); |
| 107 | + updateTabs(); |
46 | 108 | } |
47 | 109 |
|
48 | 110 | void PropertiesDock::selectCustomProperty(const QString &name) |
@@ -82,6 +144,119 @@ void PropertiesDock::bringToFront() |
82 | 144 | void PropertiesDock::retranslateUi() |
83 | 145 | { |
84 | 146 | setWindowTitle(tr("Properties")); |
| 147 | + |
| 148 | + mTabBar->setTabText(MapTab, tr("Map")); |
| 149 | + mTabBar->setTabText(LayerTab, tr("Layer")); |
| 150 | + mTabBar->setTabText(MapObjectTab, tr("Object")); |
| 151 | + mTabBar->setTabText(TilesetTab, tr("Tileset")); |
| 152 | + mTabBar->setTabText(TileTab, tr("Tile")); |
| 153 | + mTabBar->setTabText(WangSetTab, tr("Terrain Set")); |
| 154 | + mTabBar->setTabText(WangColorTab, tr("Terrain")); |
| 155 | +} |
| 156 | + |
| 157 | +void PropertiesDock::updateTabs() |
| 158 | +{ |
| 159 | + const bool isMap = mDocument && mDocument->type() == Document::MapDocumentType; |
| 160 | + const bool isTileset = mDocument && mDocument->type() == Document::TilesetDocumentType; |
| 161 | + const auto currentObject = mDocument ? mDocument->currentObject() : nullptr; |
| 162 | + |
| 163 | + bool layersSelected = false; |
| 164 | + bool objectsSelected = false; |
| 165 | + bool tilesSelected = false; |
| 166 | + bool wangSetSelected = false; |
| 167 | + bool wangColorSelected = false; |
| 168 | + |
| 169 | + if (isMap) { |
| 170 | + const auto mapDocument = static_cast<MapDocument *>(mDocument); |
| 171 | + layersSelected = !mapDocument->selectedLayers().isEmpty(); |
| 172 | + objectsSelected = !mapDocument->selectedObjects().isEmpty(); |
| 173 | + } |
| 174 | + |
| 175 | + if (isTileset) { |
| 176 | + const auto tilesetDocument = static_cast<TilesetDocument *>(mDocument); |
| 177 | + tilesSelected = !tilesetDocument->selectedTiles().isEmpty(); |
| 178 | + |
| 179 | + // todo: keep track of selected wang set and color in TilesetDocument |
| 180 | + wangSetSelected = currentObject && currentObject->typeId() == Object::WangSetType; |
| 181 | + wangColorSelected = currentObject && currentObject->typeId() == Object::WangColorType; |
| 182 | + } |
| 183 | + |
| 184 | + mTabBar->setTabVisible(MapTab, isMap); |
| 185 | + mTabBar->setTabVisible(LayerTab, layersSelected); |
| 186 | + mTabBar->setTabVisible(MapObjectTab, objectsSelected); |
| 187 | + mTabBar->setTabVisible(TilesetTab, isTileset); |
| 188 | + mTabBar->setTabVisible(TileTab, tilesSelected); |
| 189 | + mTabBar->setTabVisible(WangSetTab, wangSetSelected); |
| 190 | + mTabBar->setTabVisible(WangColorTab, wangColorSelected || wangSetSelected); |
| 191 | + mTabBar->tabRect(0); // Force recalculation of tab sizes |
| 192 | + |
| 193 | + int currentIndex = -1; |
| 194 | + if (currentObject) { |
| 195 | + switch (currentObject->typeId()) { |
| 196 | + case Object::LayerType: currentIndex = LayerTab; break; |
| 197 | + case Object::MapObjectType: currentIndex = MapObjectTab; break; |
| 198 | + case Object::MapType: currentIndex = MapTab; break; |
| 199 | + case Object::TilesetType: currentIndex = TilesetTab; break; |
| 200 | + case Object::TileType: currentIndex = TileTab; break; |
| 201 | + case Object::WangSetType: currentIndex = WangSetTab; break; |
| 202 | + case Object::WangColorType: currentIndex = WangColorTab; break; |
| 203 | + |
| 204 | + case Object::ProjectType: |
| 205 | + case Object::WorldType: |
| 206 | + currentIndex = -1; break; |
| 207 | + break; |
| 208 | + } |
| 209 | + } |
| 210 | + if (currentIndex == -1) { |
| 211 | + if (isMap) |
| 212 | + currentIndex = MapTab; |
| 213 | + else if (isTileset) |
| 214 | + currentIndex = TilesetTab; |
| 215 | + } |
| 216 | + if (currentIndex != -1 && !mTabBar->isTabVisible(currentIndex)) |
| 217 | + currentIndex = -1; |
| 218 | + mTabBar->setCurrentIndex(currentIndex); |
| 219 | +} |
| 220 | + |
| 221 | +void PropertiesDock::tabChanged(int index) |
| 222 | +{ |
| 223 | + switch (static_cast<TabType>(index)) { |
| 224 | + case MapTab: { |
| 225 | + if (auto mapDocument = qobject_cast<MapDocument *>(mDocument)) |
| 226 | + mapDocument->setCurrentObject(mapDocument->map()); |
| 227 | + break; |
| 228 | + } |
| 229 | + case LayerTab: |
| 230 | + if (auto mapDocument = qobject_cast<MapDocument *>(mDocument)) { |
| 231 | + if (auto layer = mapDocument->currentLayer()) |
| 232 | + mapDocument->setCurrentObject(layer); |
| 233 | + } |
| 234 | + break; |
| 235 | + case MapObjectTab: |
| 236 | + // todo: keep track of last focused object |
| 237 | + if (auto mapDocument = qobject_cast<MapDocument *>(mDocument)) { |
| 238 | + auto selectedObjects = mapDocument->selectedObjects(); |
| 239 | + if (!selectedObjects.isEmpty()) |
| 240 | + mapDocument->setCurrentObject(selectedObjects.first()); |
| 241 | + } |
| 242 | + break; |
| 243 | + case TilesetTab: { |
| 244 | + if (auto tilesetDocument = qobject_cast<TilesetDocument *>(mDocument)) |
| 245 | + tilesetDocument->setCurrentObject(tilesetDocument->tileset().data()); |
| 246 | + break; |
| 247 | + } |
| 248 | + case TileTab: |
| 249 | + // todo: keep track of last focused tile |
| 250 | + if (auto tilesetDocument = qobject_cast<TilesetDocument *>(mDocument)) { |
| 251 | + auto selectedTiles = tilesetDocument->selectedTiles(); |
| 252 | + if (!selectedTiles.isEmpty()) |
| 253 | + tilesetDocument->setCurrentObject(selectedTiles.first()); |
| 254 | + } |
| 255 | + case WangSetTab: |
| 256 | + case WangColorTab: |
| 257 | + // todo: keep track of selected wang set and color |
| 258 | + break; |
| 259 | + } |
85 | 260 | } |
86 | 261 |
|
87 | 262 | } // namespace Tiled |
|
0 commit comments