Skip to content
Browse files

Implemented editing of terrain information

This is done in a dedicated dialog to avoid complicated interactions
within the main UI. The dialog can be opened from the tileset dock.

The TerrainModel now represents all terrain types of a map grouped by
the tileset they appear in.

The terrain information overlay painted on top of tiles currently only
supports tiles in orthogonal mode. It does not adjust appropriately to
isometric tiles and may also have problems with orthogonal tiles that
do not match the map grid size.

All operations are properly backed by undo/redo support.

Transition distances are now recalculated on-demand. This removes the
option of tweaking distances to achieve transition priorities. That
functionality will have to be added some other way (for example with a
separate list of transition cost modifiers).

This change also happens to close #294.
  • Loading branch information...
1 parent 2b2797f commit 55fa900adb6fa2db69941431dd01460a0e0fb351 @bjorn committed Dec 3, 2012
Showing with 2,100 additions and 674 deletions.
  1. +4 −4 examples/desert.tsx
  2. +2 −2 examples/isometric_grass_and_water.tmx
  3. +6 −5 src/libtiled/libtiled.pro
  4. +10 −0 src/libtiled/map.h
  5. +3 −20 src/libtiled/mapreader.cpp
  6. +2 −17 src/libtiled/mapwriter.cpp
  7. +22 −11 src/libtiled/terrain.h
  8. +47 −0 src/libtiled/tile.cpp
  9. +21 −8 src/libtiled/tile.h
  10. +58 −8 src/libtiled/tileset.cpp
  11. +51 −8 src/libtiled/tileset.h
  12. +81 −0 src/tiled/addremoveterrain.cpp
  13. +87 −0 src/tiled/addremoveterrain.h
  14. +135 −0 src/tiled/changetileterrain.cpp
  15. +88 −0 src/tiled/changetileterrain.h
  16. +260 −0 src/tiled/editterraindialog.cpp
  17. +73 −0 src/tiled/editterraindialog.h
  18. +257 −0 src/tiled/editterraindialog.ui
  19. BIN src/tiled/images/16x16/terrain.png
  20. BIN src/tiled/images/24x24/terrain.png
  21. +1 −1 src/tiled/layermodel.cpp
  22. +1 −1 src/tiled/layermodel.h
  23. +9 −0 src/tiled/mapdocument.cpp
  24. +20 −2 src/tiled/mapdocument.h
  25. +2 −2 src/tiled/mapobjectmodel.cpp
  26. +5 −0 src/tiled/mapobjectmodel.h
  27. +21 −333 src/tiled/terraindock.cpp
  28. +5 −46 src/tiled/terraindock.h
  29. +196 −23 src/tiled/terrainmodel.cpp
  30. +52 −18 src/tiled/terrainmodel.h
  31. +19 −111 src/tiled/terrainview.cpp
  32. +6 −10 src/tiled/terrainview.h
  33. +8 −1 src/tiled/tiled.pro
  34. +2 −0 src/tiled/tiled.qrc
  35. +40 −19 src/tiled/tilesetdock.cpp
  36. +6 −0 src/tiled/tilesetdock.h
  37. +65 −1 src/tiled/tilesetmodel.cpp
  38. +32 −0 src/tiled/tilesetmodel.h
  39. +343 −21 src/tiled/tilesetview.cpp
  40. +58 −1 src/tiled/tilesetview.h
  41. +2 −1 src/tiled/undocommands.h
View
8 examples/desert.tsx
@@ -2,10 +2,10 @@
<tileset name="Desert" tilewidth="32" tileheight="32" spacing="1" margin="1">
<image source="tmw_desert_spacing.png" width="265" height="199"/>
<terraintypes>
- <terrain name="Desert" tile="29" distances=",0,1,1,1"/>
- <terrain name="Brick" tile="9" distances=",1,0,2,2"/>
- <terrain name="Cobblestone" tile="33" distances=",1,2,0,2"/>
- <terrain name="Dirt" tile="14" distances=",1,2,2,0"/>
+ <terrain name="Desert" tile="29"/>
+ <terrain name="Brick" tile="9"/>
+ <terrain name="Cobblestone" tile="33"/>
+ <terrain name="Dirt" tile="14"/>
</terraintypes>
<tile id="0" terrain="0,0,0,1"/>
<tile id="1" terrain="0,0,1,1"/>
View
4 examples/isometric_grass_and_water.tmx
@@ -4,8 +4,8 @@
<tileoffset x="0" y="16"/>
<image source="isometric_grass_and_water.png" width="256" height="384"/>
<terraintypes>
- <terrain name="Grass" tile="0" distances=",0,1"/>
- <terrain name="Water" tile="22" distances=",1,0"/>
+ <terrain name="Grass" tile="0"/>
+ <terrain name="Water" tile="22"/>
</terraintypes>
<tile id="0" terrain="0,0,0,0"/>
<tile id="1" terrain="0,0,0,0"/>
View
11 src/libtiled/libtiled.pro
@@ -26,6 +26,7 @@ DEFINES += TILED_LIBRARY
contains(QT_CONFIG, reduce_exports): CONFIG += hide_symbols
SOURCES += compression.cpp \
+ gidmapper.cpp \
imagelayer.cpp \
isometricrenderer.cpp \
layer.cpp \
@@ -38,10 +39,11 @@ SOURCES += compression.cpp \
orthogonalrenderer.cpp \
properties.cpp \
staggeredrenderer.cpp \
+ tile.cpp \
tilelayer.cpp \
- tileset.cpp \
- gidmapper.cpp
+ tileset.cpp
HEADERS += compression.h \
+ gidmapper.h \
imagelayer.h \
isometricrenderer.h \
layer.h \
@@ -57,12 +59,11 @@ HEADERS += compression.h \
orthogonalrenderer.h \
properties.h \
staggeredrenderer.h \
+ terrain.h \
tile.h \
tiled_global.h \
tilelayer.h \
- tileset.h \
- gidmapper.h \
- terrain.h
+ tileset.h
contains(INSTALL_HEADERS, yes) {
headers.files = $${HEADERS}
View
10 src/libtiled/map.h
@@ -266,6 +266,16 @@ class TILEDSHARED_EXPORT Map : public Object
void replaceTileset(Tileset *oldTileset, Tileset *newTileset);
/**
+ * Returns the number of tilesets of this map.
+ */
+ int tilesetCount() const { return mTilesets.size(); }
+
+ /**
+ * Returns the tileset at the given index.
+ */
+ Tileset *tilesetAt(int index) const { return mTilesets.at(index); }
+
+ /**
* Returns the tilesets that the tiles on this map are using.
*/
const QList<Tileset*> &tilesets() const { return mTilesets; }
View
23 src/libtiled/mapreader.cpp
@@ -321,9 +321,6 @@ Tileset *MapReaderPrivate::readTileset()
if (tileset && !mReadingExternalTileset)
mGidMapper.insert(firstGid, tileset);
- if (tileset)
- tileset->calculateTerrainDistances();
-
return tileset;
}
@@ -443,32 +440,18 @@ void MapReaderPrivate::readTilesetTerrainTypes(Tileset *tileset)
const QXmlStreamAttributes atts = xml.attributes();
QString name = atts.value(QLatin1String("name")).toString();
int tile = atts.value(QLatin1String("tile")).toString().toInt();
-// int tile = atts.value(QLatin1String("color")).toString().toInt();
-
- Terrain *terrain = new Terrain(tileset->terrainCount(), tileset, name, tile);
- QString distances = atts.value(QLatin1String("distances")).toString();
- if (!distances.isEmpty()) {
- QStringList distStrings = distances.split(QLatin1Char(','));
- QVector<int> dist(distStrings.size(), -1);
- for (int i = 0; i < distStrings.size(); ++i) {
- if (!distStrings[i].isEmpty())
- dist[i] = distStrings[i].toInt();
- }
- terrain->setTransitionDistances(dist);
- }
+ Terrain *terrain = tileset->addTerrain(name, tile);
while (xml.readNextStartElement()) {
if (xml.name() == QLatin1String("properties"))
terrain->mergeProperties(readProperties());
else
readUnknownElement();
}
-
- tileset->addTerrain(terrain);
- }
- else
+ } else {
readUnknownElement();
+ }
}
}
View
19 src/libtiled/mapwriter.cpp
@@ -213,19 +213,6 @@ static QString makeTerrainAttribute(const Tile *tile)
return terrain;
}
-static QString makeTransitionDistanceAttribute(const Terrain *t, int numTerains)
-{
- QString distance;
- for (int i = -1; i < numTerains; ++i ) {
- if (i > -1)
- distance += QLatin1String(",");
- int d = t->transitionDistance(i);
- if (d > -1)
- distance += QString::number(d);
- }
- return distance;
-}
-
void MapWriterPrivate::writeTileset(QXmlStreamWriter &w, const Tileset *tileset,
uint firstGid)
{
@@ -298,11 +285,9 @@ void MapWriterPrivate::writeTileset(QXmlStreamWriter &w, const Tileset *tileset,
for (int i = 0; i < tileset->terrainCount(); ++i) {
Terrain* t = tileset->terrain(i);
w.writeStartElement(QLatin1String("terrain"));
+
w.writeAttribute(QLatin1String("name"), t->name());
-// w.writeAttribute(QLatin1String("color"), tt->color());
- w.writeAttribute(QLatin1String("tile"), QString::number(t->paletteImageTile()));
- if (t->hasTransitionDistances())
- w.writeAttribute(QLatin1String("distances"), makeTransitionDistanceAttribute(t, tileset->terrainCount()));
+ w.writeAttribute(QLatin1String("tile"), QString::number(t->imageTileId()));
writeProperties(w, t->properties());
View
33 src/libtiled/terrain.h
@@ -46,20 +46,25 @@ class Tile;
class TILEDSHARED_EXPORT Terrain : public Object
{
public:
- Terrain(int id, Tileset *tileset, QString name, int imageTile):
+ Terrain(int id, Tileset *tileset, QString name, int imageTileId):
mId(id),
mTileset(tileset),
mName(name),
- mImageTile(imageTile)
+ mImageTileId(imageTileId)
{
}
/**
- * Returns ID of this tile terrain type.
+ * Returns ID of this terrain type.
*/
int id() const { return this != NULL ? mId : -1; }
/**
+ * Sets the ID of this terrain type.
+ */
+ void setId(int id) { mId = id; }
+
+ /**
* Returns the tileset this terrain type belongs to.
*/
Tileset *tileset() const { return mTileset; }
@@ -70,19 +75,25 @@ class TILEDSHARED_EXPORT Terrain : public Object
QString name() const { return mName; }
/**
- * Returns a tile index that represents this terrain type in the terrain palette.
+ * Sets the name of this terrain type.
*/
- int paletteImageTile() const { return mImageTile; }
+ void setName(const QString &name) { mName = name; }
/**
- * Returns a Tile that represents this terrain type in the terrain palette.
+ * Returns the index of the tile that visually represents this terrain type.
*/
- Tile *paletteImage() const { return mTileset->tileAt(mImageTile); }
+ int imageTileId() const { return mImageTileId; }
/**
- * Returns true if this terrain type already has transition distances calculated.
+ * Sets the index of the tile that visually represents this terrain type.
+ */
+ void setImageTileId(int imageTileId) { mImageTileId = imageTileId; }
+
+ /**
+ * Returns a Tile that represents this terrain type in the terrain palette.
*/
- bool hasTransitionDistances() const { return !mTransitionDistance.isEmpty(); }
+ Tile *imageTile() const
+ { return mImageTileId >= 0 ? mTileset->tileAt(mImageTileId) : 0; }
/**
* Returns the transition penalty(/distance) from this terrain type to another terrain type.
@@ -97,13 +108,13 @@ class TILEDSHARED_EXPORT Terrain : public Object
/**
* Returns the array of terrain penalties(/distances).
*/
- void setTransitionDistances(QVector<int> &transitionDistances) { mTransitionDistance = transitionDistances; }
+ void setTransitionDistances(const QVector<int> &transitionDistances) { mTransitionDistance = transitionDistances; }
private:
int mId;
Tileset *mTileset;
QString mName;
- int mImageTile;
+ int mImageTileId;
QVector<int> mTransitionDistance;
};
View
47 src/libtiled/tile.cpp
@@ -0,0 +1,47 @@
+/*
+ * tile.cpp
+ * Copyright 2012, Thorbjørn Lindeijer <thorbjorn@lindeijer.nl>
+ *
+ * This file is part of libtiled.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tile.h"
+
+#include "tileset.h"
+
+using namespace Tiled;
+
+Terrain *Tile::terrainAtCorner(int corner) const
+{
+ return mTileset->terrain(cornerTerrainId(corner));
+}
+
+void Tile::setTerrain(unsigned int terrain)
+{
+ if (mTerrain == terrain)
+ return;
+
+ mTerrain = terrain;
+ mTileset->markTerrainDistancesDirty();
+}
View
29 src/libtiled/tile.h
@@ -1,6 +1,6 @@
/*
* tile.h
- * Copyright 2008-2009, Thorbjørn Lindeijer <thorbjorn@lindeijer.nl>
+ * Copyright 2008-2012, Thorbjørn Lindeijer <thorbjorn@lindeijer.nl>
* Copyright 2009, Edward Hutchins <eah1@yahoo.com>
*
* This file is part of libtiled.
@@ -31,12 +31,24 @@
#define TILE_H
#include "object.h"
-#include "tileset.h"
#include <QPixmap>
namespace Tiled {
+class Terrain;
+class Tileset;
+
+/**
+ * Returns the given \a terrain with the \a corner modified to \a terrainId.
+ */
+inline unsigned setTerrainCorner(unsigned terrain, int corner, int terrainId)
+{
+ unsigned int mask = 0xFF << (3 - corner) * 8;
+ unsigned int insert = terrainId << (3 - corner) * 8;
+ return (terrain & ~mask) | (insert & mask);
+}
+
class TILEDSHARED_EXPORT Tile : public Object
{
public:
@@ -86,7 +98,7 @@ class TILEDSHARED_EXPORT Tile : public Object
/**
* Returns the Terrain of a given corner.
*/
- Terrain *terrainAtCorner(int corner) const { return mTileset->terrain(cornerTerrainId(corner)); }
+ Terrain *terrainAtCorner(int corner) const;
/**
* Returns the terrain id at a given corner.
@@ -97,11 +109,7 @@ class TILEDSHARED_EXPORT Tile : public Object
* Set the terrain type of a given corner.
*/
void setCornerTerrain(int corner, int terrainId)
- {
- unsigned int mask = 0xFF << (3 - corner)*8;
- unsigned int insert = terrainId << (3 - corner)*8;
- mTerrain = (mTerrain & ~mask) | (insert & mask);
- }
+ { setTerrain(setTerrainCorner(mTerrain, corner, terrainId)); }
/**
* Functions to get various terrain type information from tiles.
@@ -113,6 +121,11 @@ class TILEDSHARED_EXPORT Tile : public Object
unsigned int terrain() const { return this == NULL ? 0xFFFFFFFF : mTerrain; } // HACK: NULL Tile has 'none' terrain type.
/**
+ * Set the terrain for each corner of the tile.
+ */
+ void setTerrain(unsigned int terrain);
+
+ /**
* Returns the probability of this terrain type appearing while painting (0-100%).
*/
float terrainProbability() const { return mTerrainProbability; }
View
66 src/libtiled/tileset.cpp
@@ -114,25 +114,78 @@ int Tileset::columnCountForWidth(int width) const
return (width - mMargin + mTileSpacing) / (mTileWidth + mTileSpacing);
}
-void Tileset::addTerrain(Terrain *terrain)
+Terrain *Tileset::addTerrain(const QString &name, int imageTileId)
{
- mTerrainTypes.push_back(terrain);
+ Terrain *terrain = new Terrain(terrainCount(), this, name, imageTileId);
+ insertTerrain(terrainCount(), terrain);
+ return terrain;
+}
+
+void Tileset::insertTerrain(int index, Terrain *terrain)
+{
+ Q_ASSERT(terrain->tileset() == this);
+
+ mTerrainTypes.insert(index, terrain);
+
+ // Reassign terrain IDs
+ for (int terrainId = index; terrainId < mTerrainTypes.size(); ++terrainId)
+ mTerrainTypes.at(terrainId)->setId(terrainId);
+
+ // Adjust tile terrain references
+ foreach (Tile *tile, mTiles) {
+ for (int corner = 0; corner < 4; ++corner) {
+ const int terrainId = tile->cornerTerrainId(corner);
+ if (terrainId >= index)
+ tile->setCornerTerrain(corner, terrainId + 1);
+ }
+ }
+
+ mTerrainDistancesDirty = true;
+}
+
+Terrain *Tileset::takeTerrainAt(int index)
+{
+ Terrain *terrain = mTerrainTypes.takeAt(index);
+
+ // Reassign terrain IDs
+ for (int terrainId = index; terrainId < mTerrainTypes.size(); ++terrainId)
+ mTerrainTypes.at(terrainId)->setId(terrainId);
+
+ // Clear and adjust tile terrain references
+ foreach (Tile *tile, mTiles) {
+ for (int corner = 0; corner < 4; ++corner) {
+ const int terrainId = tile->cornerTerrainId(corner);
+ if (terrainId == index)
+ tile->setCornerTerrain(corner, 0xFF);
+ else if (terrainId > index)
+ tile->setCornerTerrain(corner, terrainId - 1);
+ }
+ }
+
+ mTerrainDistancesDirty = true;
+
+ return terrain;
}
int Tileset::terrainTransitionPenalty(int terrainType0, int terrainType1)
{
+ if (mTerrainDistancesDirty) {
+ recalculateTerrainDistances();
+ mTerrainDistancesDirty = false;
+ }
+
terrainType0 = terrainType0 == 255 ? -1 : terrainType0;
terrainType1 = terrainType1 == 255 ? -1 : terrainType1;
// Do some magic, since we don't have a transition array for no-terrain
if (terrainType0 == -1 && terrainType1 == -1)
return 0;
if (terrainType0 == -1)
- return mTerrainTypes[terrainType1]->transitionDistance(terrainType0);
- return mTerrainTypes[terrainType0]->transitionDistance(terrainType1);
+ return mTerrainTypes.at(terrainType1)->transitionDistance(terrainType0);
+ return mTerrainTypes.at(terrainType0)->transitionDistance(terrainType1);
}
-void Tileset::calculateTerrainDistances()
+void Tileset::recalculateTerrainDistances()
{
// some fancy macros which can search for a value in each byte of a word simultaneously
#define hasZeroByte(dword) (((dword) - 0x01010101UL) & ~(dword) & 0x80808080UL)
@@ -144,9 +197,6 @@ void Tileset::calculateTerrainDistances()
for (int i = 0; i < terrainCount(); ++i) {
Terrain *type = terrain(i);
- if (type->hasTransitionDistances())
- continue;
-
QVector<int> distance(terrainCount() + 1, -1);
// Check all tiles for transitions to other terrain types
View
59 src/libtiled/tileset.h
@@ -73,7 +73,8 @@ class TILEDSHARED_EXPORT Tileset : public Object
mMargin(margin),
mImageWidth(0),
mImageHeight(0),
- mColumnCount(0)
+ mColumnCount(0),
+ mTerrainDistancesDirty(false)
{
Q_ASSERT(tileSpacing >= 0);
Q_ASSERT(margin >= 0);
@@ -121,6 +122,11 @@ class TILEDSHARED_EXPORT Tileset : public Object
int tileHeight() const { return mTileHeight; }
/**
+ * Returns the maximum size of the tiles in this tileset.
+ */
+ QSize tileSize() const { return QSize(mTileWidth, mTileHeight); }
+
+ /**
* Returns the spacing between the tiles in the tileset image.
*/
int tileSpacing() const { return mTileSpacing; }
@@ -142,6 +148,11 @@ class TILEDSHARED_EXPORT Tileset : public Object
void setTileOffset(QPoint offset) { mTileOffset = offset; }
/**
+ * Returns a const reference to the list of tiles in this tileset.
+ */
+ const QList<Tile*> &tiles() const { return mTiles; }
+
+ /**
* Returns the tile for the given tile ID.
* The tile ID is local to this tileset, which means the IDs are in range
* [0, tileCount() - 1].
@@ -217,24 +228,45 @@ class TILEDSHARED_EXPORT Tileset : public Object
int columnCountForWidth(int width) const;
/**
+ * Returns a const reference to the list of terrains in this tileset.
+ */
+ const QList<Terrain*> &terrains() const { return mTerrainTypes; }
+
+ /**
* Returns the number of terrain types in this tileset.
*/
int terrainCount() const { return mTerrainTypes.size(); }
/**
- * Returns the number of tiles in this tileset.
+ * Returns the terrain type at the given \a index.
*/
- Terrain *terrain(int terrain) const { return terrain >= 0 ? mTerrainTypes[terrain] : NULL; }
+ Terrain *terrain(int index) const { return index >= 0 ? mTerrainTypes[index] : 0; }
/**
- * Add a new terrain type.
+ * Adds a new terrain type.
+ *
+ * @param name the name of the terrain
+ * @param imageTile the id of the tile that represents the terrain visually
+ * @return the created Terrain instance
*/
- void addTerrain(Terrain *terrain);
+ Terrain *addTerrain(const QString &name, int imageTileId);
/**
- * Calculates the transition distance matrix for all terrain types.
+ * Adds the \a terrain type at the given \a index.
+ *
+ * The terrain should already have this tileset associated with it.
+ */
+ void insertTerrain(int index, Terrain *terrain);
+
+ /**
+ * Removes the terrain type at the given \a index and returns it. The
+ * caller becomes responsible for the lifetime of the terrain type.
+ *
+ * This will cause the terrain ids of subsequent terrains to shift up to
+ * fill the space and the terrain information of all tiles in this tileset
+ * will be updated accordingly.
*/
- void calculateTerrainDistances();
+ Terrain *takeTerrainAt(int index);
/**
* Returns the transition penalty(/distance) between 2 terrains. -1 if no transition is possible.
@@ -251,6 +283,11 @@ class TILEDSHARED_EXPORT Tileset : public Object
*/
void setTileImage(int index, const QPixmap &image);
+ /**
+ * Used by the Tile class when its terrain information changes.
+ */
+ void markTerrainDistancesDirty() { mTerrainDistancesDirty = true; }
+
private:
/**
* Detaches from the external image. Should be called everytime the tileset
@@ -259,10 +296,15 @@ class TILEDSHARED_EXPORT Tileset : public Object
void detachExternalImage();
/**
- * Sets tile size to the maximum size
+ * Sets tile size to the maximum size.
*/
void updateTileSize();
+ /**
+ * Calculates the transition distance matrix for all terrain types.
+ */
+ void recalculateTerrainDistances();
+
QString mName;
QString mFileName;
QString mImageSource;
@@ -277,6 +319,7 @@ class TILEDSHARED_EXPORT Tileset : public Object
int mColumnCount;
QList<Tile*> mTiles;
QList<Terrain*> mTerrainTypes;
+ bool mTerrainDistancesDirty;
};
} // namespace Tiled
View
81 src/tiled/addremoveterrain.cpp
@@ -0,0 +1,81 @@
+/*
+ * addremoveterrain.cpp
+ * Copyright 2012, Thorbjørn Lindeijer <thorbjorn@lindeijer.nl>
+ *
+ * This file is part of Tiled.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "addremoveterrain.h"
+
+#include "mapdocument.h"
+#include "terrain.h"
+#include "terrainmodel.h"
+#include "tileset.h"
+
+#include <QCoreApplication>
+
+using namespace Tiled;
+using namespace Tiled::Internal;
+
+AddRemoveTerrain::AddRemoveTerrain(MapDocument *mapDocument,
+ Tileset *tileset,
+ int index,
+ Terrain *terrain)
+ : mMapDocument(mapDocument)
+ , mTileset(tileset)
+ , mIndex(index)
+ , mTerrain(terrain)
+ , mTerrainAdded(false)
+{
+}
+
+AddRemoveTerrain::~AddRemoveTerrain()
+{
+ delete mTerrain;
+}
+
+void AddRemoveTerrain::removeTerrain()
+{
+ Q_ASSERT(!mTerrain);
+ mTerrain = mMapDocument->terrainModel()->takeTerrainAt(mTileset, mIndex);
+}
+
+void AddRemoveTerrain::addTerrain()
+{
+ Q_ASSERT(mTerrain);
+ mMapDocument->terrainModel()->insertTerrain(mTileset, mIndex, mTerrain);
+ mTerrain = 0;
+}
+
+
+AddTerrain::AddTerrain(MapDocument *mapDocument, Terrain *terrain)
+ : AddRemoveTerrain(mapDocument,
+ terrain->tileset(),
+ terrain->tileset()->terrainCount(),
+ terrain)
+{
+ setText(QCoreApplication::translate("Undo Commands", "Add Terrain"));
+}
+
+
+RemoveTerrain::RemoveTerrain(MapDocument *mapDocument, Terrain *terrain)
+ : AddRemoveTerrain(mapDocument,
+ terrain->tileset(),
+ terrain->id(),
+ 0)
+{
+ setText(QCoreApplication::translate("Undo Commands", "Remove Terrain"));
+}
View
87 src/tiled/addremoveterrain.h
@@ -0,0 +1,87 @@
+/*
+ * addremoveterrain.h
+ * Copyright 2012, Thorbjørn Lindeijer <thorbjorn@lindeijer.nl>
+ *
+ * This file is part of Tiled.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ADDREMOVETERRAIN_H
+#define ADDREMOVETERRAIN_H
+
+#include <QUndoCommand>
+
+namespace Tiled {
+
+class Terrain;
+class Tileset;
+
+namespace Internal {
+
+class MapDocument;
+
+/**
+ * Abstract base class for AddTerrain and RemoveTerrain.
+ */
+class AddRemoveTerrain : public QUndoCommand
+{
+public:
+ AddRemoveTerrain(MapDocument *mapDocument,
+ Tileset *tileset,
+ int index,
+ Terrain *terrain);
+ ~AddRemoveTerrain();
+
+protected:
+ void addTerrain();
+ void removeTerrain();
+
+private:
+ MapDocument *mMapDocument;
+ Tileset *mTileset;
+ int mIndex;
+ Terrain *mTerrain;
+ bool mTerrainAdded;
+};
+
+
+/**
+ * Adds a terrain to a map.
+ */
+class AddTerrain : public AddRemoveTerrain
+{
+public:
+ AddTerrain(MapDocument *mapDocument, Terrain *terrain);
+
+ void undo() { removeTerrain(); }
+ void redo() { addTerrain(); }
+};
+
+/**
+ * Removes a terrain from a map.
+ */
+class RemoveTerrain : public AddRemoveTerrain
+{
+public:
+ RemoveTerrain(MapDocument *mapDocument, Terrain *terrain);
+
+ void undo() { addTerrain(); }
+ void redo() { removeTerrain(); }
+};
+
+} // namespace Internal
+} // namespace Tiled
+
+#endif // ADDREMOVETERRAIN_H
View
135 src/tiled/changetileterrain.cpp
@@ -0,0 +1,135 @@
+/*
+ * changetileterrain.cpp
+ * Copyright 2012, Thorbjørn Lindeijer <thorbjorn@lindeijer.nl>
+ *
+ * This file is part of Tiled.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "changetileterrain.h"
+
+#include "mapdocument.h"
+#include "tile.h"
+
+#include <QCoreApplication>
+
+namespace Tiled {
+namespace Internal {
+
+ChangeTileTerrain::ChangeTileTerrain()
+ : mMapDocument(0)
+ , mTileset(0)
+ , mMergeable(false)
+{
+ initText();
+}
+
+ChangeTileTerrain::ChangeTileTerrain(MapDocument *mapDocument,
+ Tile *tile, unsigned terrain)
+ : mMapDocument(mapDocument)
+ , mTileset(tile->tileset())
+ , mMergeable(true)
+{
+ initText();
+ mChanges.insert(tile, Change(tile->terrain(), terrain));
+}
+
+ChangeTileTerrain::ChangeTileTerrain(MapDocument *mapDocument,
+ const Changes &changes)
+ : mMapDocument(mapDocument)
+ , mTileset(changes.begin().key()->tileset())
+ , mChanges(changes)
+ , mMergeable(true)
+{
+ initText();
+}
+
+void ChangeTileTerrain::undo()
+{
+ Changes::const_iterator i = mChanges.constBegin();
+
+ QList<Tile *> changedTiles;
+ changedTiles.reserve(mChanges.size());
+
+ while (i != mChanges.constEnd()) {
+ Tile *tile = i.key();
+ const Change &change = i.value();
+
+ tile->setTerrain(change.from);
+ changedTiles.append(tile);
+
+ ++i;
+ }
+
+ mMapDocument->emitTileTerrainChanged(changedTiles);
+}
+
+void ChangeTileTerrain::redo()
+{
+ Changes::const_iterator i = mChanges.constBegin();
+
+ QList<Tile *> changedTiles;
+ changedTiles.reserve(mChanges.size());
+
+ while (i != mChanges.constEnd()) {
+ Tile *tile = i.key();
+ const Change &change = i.value();
+
+ tile->setTerrain(change.to);
+ changedTiles.append(tile);
+
+ ++i;
+ }
+
+ mMapDocument->emitTileTerrainChanged(changedTiles);
+}
+
+bool ChangeTileTerrain::mergeWith(const QUndoCommand *other)
+{
+ if (!mMergeable)
+ return false;
+
+ const ChangeTileTerrain *o = static_cast<const ChangeTileTerrain*>(other);
+ if (o->mMapDocument && !(mMapDocument == o->mMapDocument &&
+ mTileset == o->mTileset))
+ return false;
+
+ Changes::const_iterator i = o->mChanges.constBegin();
+ Changes::const_iterator i_end = o->mChanges.constEnd();
+ while (i != i_end) {
+ Tile *tile = i.key();
+ const Change &change = i.value();
+
+ if (mChanges.contains(tile))
+ mChanges[tile].to = change.to;
+ else
+ mChanges.insert(tile, change);
+
+ ++i;
+ }
+
+ mMergeable = o->mMergeable;
+
+ return true;
+}
+
+void ChangeTileTerrain::initText()
+{
+ setText(QCoreApplication::translate("Undo Commands",
+ "Change Tile Terrain"));
+}
+
+} // namespace Internal
+} // namespace Tiled
View
88 src/tiled/changetileterrain.h
@@ -0,0 +1,88 @@
+/*
+ * changetileterrain.h
+ * Copyright 2012, Thorbjørn Lindeijer <thorbjorn@lindeijer.nl>
+ *
+ * This file is part of Tiled.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CHANGETILETERRAIN_H
+#define CHANGETILETERRAIN_H
+
+#include <QMap>
+#include <QUndoCommand>
+
+#include "undocommands.h"
+
+namespace Tiled {
+
+class Tile;
+class Tileset;
+
+namespace Internal {
+
+class MapDocument;
+
+class ChangeTileTerrain : public QUndoCommand
+{
+public:
+ struct Change {
+ Change() {}
+ Change(unsigned from, unsigned to)
+ : from(from), to(to)
+ {}
+
+ unsigned from;
+ unsigned to;
+ };
+
+ typedef QMap<Tile *, Change> Changes;
+
+ /**
+ * Constructs an empty command that changes no terrain. When merged into
+ * a previous terrain change command, it prevents that command from merging
+ * with future commands.
+ */
+ ChangeTileTerrain();
+
+ /**
+ * Changes the terrain of \a tile.
+ */
+ ChangeTileTerrain(MapDocument *mapDocument, Tile *tile, unsigned terrain);
+
+ /**
+ * Applies the given terrain \a changes.
+ */
+ ChangeTileTerrain(MapDocument *mapDocument, const Changes &changes);
+
+ void undo();
+ void redo();
+
+ int id() const { return Cmd_ChangeTileTerrain; }
+ bool mergeWith(const QUndoCommand *other);
+
+private:
+ void initText();
+
+ MapDocument *mMapDocument;
+ Tileset *mTileset;
+ Changes mChanges;
+ bool mMergeable;
+};
+
+} // namespace Internal
+} // namespace Tiled
+
+#endif // CHANGETILETERRAIN_H
View
260 src/tiled/editterraindialog.cpp
@@ -0,0 +1,260 @@
+/*
+ * editterraindialog.cpp
+ * Copyright 2012, Thorbjørn Lindeijer <thorbjorn@lindeijer.nl>
+ *
+ * This file is part of Tiled.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "editterraindialog.h"
+#include "ui_editterraindialog.h"
+
+#include "addremoveterrain.h"
+#include "changetileterrain.h"
+#include "mapdocument.h"
+#include "terrain.h"
+#include "terrainmodel.h"
+#include "tile.h"
+#include "tileset.h"
+#include "zoomable.h"
+
+#include <QUndoStack>
+
+#include <QDebug>
+
+using namespace Tiled;
+using namespace Tiled::Internal;
+
+namespace {
+
+class SetTerrainImage : public QUndoCommand
+{
+public:
+ SetTerrainImage(MapDocument *mapDocument,
+ Tileset *tileset,
+ int terrainId,
+ int tileId)
+ : QUndoCommand(QCoreApplication::translate("Undo Commands",
+ "Change Terrain Image"))
+ , mTerrainModel(mapDocument->terrainModel())
+ , mTileset(tileset)
+ , mTerrainId(terrainId)
+ , mOldImageTileId(tileset->terrain(terrainId)->imageTileId())
+ , mNewImageTileId(tileId)
+ {}
+
+ void undo()
+ { mTerrainModel->setTerrainImage(mTileset, mTerrainId, mOldImageTileId); }
+
+ void redo()
+ { mTerrainModel->setTerrainImage(mTileset, mTerrainId, mNewImageTileId); }
+
+private:
+ TerrainModel *mTerrainModel;
+ Tileset *mTileset;
+ int mTerrainId;
+ int mOldImageTileId;
+ int mNewImageTileId;
+};
+
+} // anonymous namespace
+
+
+EditTerrainDialog::EditTerrainDialog(MapDocument *mapDocument,
+ Tileset *tileset,
+ QWidget *parent)
+ : QDialog(parent)
+ , mUi(new Ui::EditTerrainDialog)
+ , mMapDocument(mapDocument)
+ , mInitialUndoStackIndex(mMapDocument->undoStack()->index())
+ , mTileset(tileset)
+{
+ mUi->setupUi(this);
+
+ Zoomable *zoomable = new Zoomable(this);
+ zoomable->connectToComboBox(mUi->zoomComboBox);
+
+ TilesetModel *tilesetModel = new TilesetModel(mTileset, mUi->tilesetView);
+ connect(mapDocument, SIGNAL(tileTerrainChanged(QList<Tile*>)),
+ tilesetModel, SLOT(tilesChanged(QList<Tile*>)));
+
+ mUi->tilesetView->setEditTerrain(true);
+ mUi->tilesetView->setMapDocument(mapDocument);
+ mUi->tilesetView->setZoomable(zoomable);
+ mUi->tilesetView->setModel(tilesetModel);
+
+ mTerrainModel = mapDocument->terrainModel();
+ const QModelIndex rootIndex = mTerrainModel->index(tileset);
+
+ mUi->terrainList->setMapDocument(mapDocument);
+ mUi->terrainList->setModel(mTerrainModel);
+ mUi->terrainList->setRootIndex(rootIndex);
+
+ QHeaderView *terrainListHeader = mUi->terrainList->header();
+#if QT_VERSION >= 0x050000
+ terrainListHeader->setSectionResizeMode(0, QHeaderView::ResizeToContents);
+#else
+ terrainListHeader->setResizeMode(0, QHeaderView::ResizeToContents);
+#endif
+
+ QItemSelectionModel *selectionModel = mUi->terrainList->selectionModel();
+ connect(selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
+ SLOT(selectedTerrainChanged(QModelIndex)));
+
+ if (mTerrainModel->rowCount(rootIndex) > 0) {
+ selectionModel->setCurrentIndex(mTerrainModel->index(0, 0, rootIndex),
+ QItemSelectionModel::SelectCurrent |
+ QItemSelectionModel::Rows);
+ mUi->terrainList->setFocus();
+ }
+
+ connect(mUi->clearTerrain, SIGNAL(toggled(bool)),
+ SLOT(clearTerrainToggled(bool)));
+
+ connect(mUi->addTerrainTypeButton, SIGNAL(clicked()),
+ SLOT(addTerrainType()));
+ connect(mUi->removeTerrainTypeButton, SIGNAL(clicked()),
+ SLOT(removeTerrainType()));
+
+ connect(mUi->tilesetView, SIGNAL(terrainImageSelected(Tile*)),
+ SLOT(setTerrainImage(Tile*)));
+
+ QUndoStack *undoStack = mapDocument->undoStack();
+ connect(undoStack, SIGNAL(indexChanged(int)),
+ SLOT(updateUndoButton()));
+ connect(undoStack, SIGNAL(canRedoChanged(bool)),
+ mUi->redo, SLOT(setEnabled(bool)));
+ connect(mUi->undo, SIGNAL(clicked()), undoStack, SLOT(undo()));
+ connect(mUi->redo, SIGNAL(clicked()), undoStack, SLOT(redo()));
+
+ updateUndoButton();
+}
+
+EditTerrainDialog::~EditTerrainDialog()
+{
+ delete mUi;
+}
+
+void EditTerrainDialog::selectedTerrainChanged(const QModelIndex &index)
+{
+ int terrainId = -1;
+ if (Terrain *terrain = mTerrainModel->terrainAt(index))
+ terrainId = terrain->id();
+
+ if (!mUi->clearTerrain->isChecked())
+ mUi->tilesetView->setTerrainId(terrainId);
+
+ mUi->removeTerrainTypeButton->setEnabled(terrainId != -1);
+}
+
+void EditTerrainDialog::clearTerrainToggled(bool checked)
+{
+ if (checked) {
+ mUi->tilesetView->setTerrainId(-1);
+ } else {
+ const QModelIndex currentIndex = mUi->terrainList->currentIndex();
+ if (Terrain *terrain = mTerrainModel->terrainAt(currentIndex))
+ mUi->tilesetView->setTerrainId(terrain->id());
+ }
+}
+
+void EditTerrainDialog::addTerrainType()
+{
+ Terrain *terrain = new Terrain(mTileset->terrainCount(), mTileset,
+ QString(), -1);
+ terrain->setName(tr("New Terrain"));
+
+ mMapDocument->undoStack()->push(new AddTerrain(mMapDocument, terrain));
+
+ // Select the newly added terrain and edit its name
+ const QModelIndex index = mTerrainModel->index(terrain, 1);
+ QItemSelectionModel *selectionModel = mUi->terrainList->selectionModel();
+ selectionModel->setCurrentIndex(index,
+ QItemSelectionModel::ClearAndSelect |
+ QItemSelectionModel::Rows);
+ mUi->terrainList->edit(index);
+}
+
+void EditTerrainDialog::removeTerrainType()
+{
+ const QModelIndex currentIndex = mUi->terrainList->currentIndex();
+ if (!currentIndex.isValid())
+ return;
+
+ Terrain *terrain = mTerrainModel->terrainAt(currentIndex);
+ RemoveTerrain *removeTerrain = new RemoveTerrain(mMapDocument, terrain);
+
+ /*
+ * Clear any references to the terrain that is about to be removed with
+ * an undo command, as a way of preserving them when undoing the removal
+ * of the terrain.
+ */
+ ChangeTileTerrain::Changes changes;
+
+ foreach (Tile *tile, terrain->tileset()->tiles()) {
+ unsigned tileTerrain = tile->terrain();
+
+ for (int corner = 0; corner < 4; ++corner) {
+ if (tile->cornerTerrainId(corner) == terrain->id())
+ tileTerrain = setTerrainCorner(tileTerrain, corner, 0xFF);
+ }
+
+ if (tileTerrain != tile->terrain()) {
+ changes.insert(tile, ChangeTileTerrain::Change(tile->terrain(),
+ tileTerrain));
+ }
+ }
+
+ QUndoStack *undoStack = mMapDocument->undoStack();
+
+ if (!changes.isEmpty()) {
+ undoStack->beginMacro(removeTerrain->text());
+ undoStack->push(new ChangeTileTerrain(mMapDocument, changes));
+ }
+
+ mMapDocument->undoStack()->push(removeTerrain);
+
+ if (!changes.isEmpty())
+ undoStack->endMacro();
+
+ /*
+ * Removing a terrain usually changes the selected terrain without the
+ * selection changing rows, so we can't rely on the currentRowChanged
+ * signal.
+ */
+ selectedTerrainChanged(mUi->terrainList->currentIndex());
+}
+
+void EditTerrainDialog::setTerrainImage(Tile *tile)
+{
+ const QModelIndex currentIndex = mUi->terrainList->currentIndex();
+ if (!currentIndex.isValid())
+ return;
+
+ Terrain *terrain = mTerrainModel->terrainAt(currentIndex);
+ mMapDocument->undoStack()->push(new SetTerrainImage(mMapDocument,
+ terrain->tileset(),
+ terrain->id(),
+ tile->id()));
+}
+
+void EditTerrainDialog::updateUndoButton()
+{
+ QUndoStack *undoStack = mMapDocument->undoStack();
+ const int index = undoStack->index();
+
+ mUi->undo->setEnabled(index > mInitialUndoStackIndex);
+ mUi->redo->setEnabled(undoStack->canRedo());
+}
View
73 src/tiled/editterraindialog.h
@@ -0,0 +1,73 @@
+/*
+ * editterraindialog.cpp
+ * Copyright 2012, Thorbjørn Lindeijer <thorbjorn@lindeijer.nl>
+ *
+ * This file is part of Tiled.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef EDITTERRAINDIALOG_H
+#define EDITTERRAINDIALOG_H
+
+#include <QDialog>
+
+class QModelIndex;
+
+namespace Ui {
+class EditTerrainDialog;
+}
+
+namespace Tiled {
+
+class Tile;
+class Tileset;
+
+namespace Internal {
+
+class MapDocument;
+class TerrainModel;
+
+class EditTerrainDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit EditTerrainDialog(MapDocument *mapDocument,
+ Tileset *tileset,
+ QWidget *parent = 0);
+ ~EditTerrainDialog();
+
+
+private slots:
+ void selectedTerrainChanged(const QModelIndex &index);
+ void clearTerrainToggled(bool checked);
+ void addTerrainType();
+ void removeTerrainType();
+ void setTerrainImage(Tile *tile);
+
+ void updateUndoButton();
+
+private:
+ Ui::EditTerrainDialog *mUi;
+ MapDocument *mMapDocument;
+ int mInitialUndoStackIndex;
+ Tileset *mTileset;
+ TerrainModel *mTerrainModel;
+};
+
+} // namespace Internal
+} // namespace Tiled
+
+#endif // EDITTERRAINDIALOG_H
View
257 src/tiled/editterraindialog.ui
@@ -0,0 +1,257 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>EditTerrainDialog</class>
+ <widget class="QDialog" name="EditTerrainDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>615</width>
+ <height>372</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Edit Terrain Information</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QToolButton" name="undo">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string>Undo</string>
+ </property>
+ <property name="text">
+ <string>Undo</string>
+ </property>
+ <property name="icon">
+ <iconset theme="edit-undo" resource="tiled.qrc">
+ <normaloff>:/images/24x24/edit-undo.png</normaloff>:/images/24x24/edit-undo.png</iconset>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="redo">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string>Redo</string>
+ </property>
+ <property name="text">
+ <string>Redo</string>
+ </property>
+ <property name="icon">
+ <iconset theme="edit-redo" resource="tiled.qrc">
+ <normaloff>:/images/24x24/edit-redo.png</normaloff>:/images/24x24/edit-redo.png</iconset>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QComboBox" name="zoomComboBox"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QPushButton" name="clearTerrain">
+ <property name="text">
+ <string>No Terrain</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Tiled::Internal::TerrainView" name="terrainList">
+ <property name="maximumSize">
+ <size>
+ <width>200</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="verticalScrollMode">
+ <enum>QAbstractItemView::ScrollPerPixel</enum>
+ </property>
+ <property name="indentation">
+ <number>0</number>
+ </property>
+ <property name="rootIsDecorated">
+ <bool>false</bool>
+ </property>
+ <property name="itemsExpandable">
+ <bool>false</bool>
+ </property>
+ <attribute name="headerVisible">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="Tiled::Internal::TilesetView" name="tilesetView">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>200</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QToolButton" name="addTerrainTypeButton">
+ <property name="toolTip">
+ <string>Add Terrain Type</string>
+ </property>
+ <property name="text">
+ <string>Add</string>
+ </property>
+ <property name="icon">
+ <iconset resource="tiled.qrc">
+ <normaloff>:/images/22x22/add.png</normaloff>:/images/22x22/add.png</iconset>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="removeTerrainTypeButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string>Remove Terrain Type</string>
+ </property>
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ <property name="icon">
+ <iconset resource="tiled.qrc">
+ <normaloff>:/images/22x22/remove.png</normaloff>:/images/22x22/remove.png</iconset>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>Tiled::Internal::TilesetView</class>
+ <extends>QTableView</extends>
+ <header location="global">tilesetview.h</header>
+ </customwidget>
+ <customwidget>
+ <class>Tiled::Internal::TerrainView</class>
+ <extends>QTreeView</extends>
+ <header location="global">terrainview.h</header>
+ </customwidget>
+ </customwidgets>
+ <tabstops>
+ <tabstop>tilesetView</tabstop>
+ <tabstop>addTerrainTypeButton</tabstop>
+ <tabstop>removeTerrainTypeButton</tabstop>
+ <tabstop>buttonBox</tabstop>
+ </tabstops>
+ <resources>
+ <include location="tiled.qrc"/>
+ </resources>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>EditTerrainDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>227</x>
+ <y>346</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>EditTerrainDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>295</x>
+ <y>352</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
View
BIN src/tiled/images/16x16/terrain.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN src/tiled/images/24x24/terrain.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
2 src/tiled/layermodel.cpp
@@ -202,7 +202,7 @@ bool LayerModel::setData(const QModelIndex &index, const QVariant &value,
const QString newName = value.toString();
if (layer->name() != newName) {
RenameLayer *rename = new RenameLayer(mMapDocument, layerIndex,
- value.toString());
+ newName);
mMapDocument->undoStack()->push(rename);
}
return true;
View
2 src/tiled/layermodel.h
@@ -73,7 +73,7 @@ class LayerModel : public QAbstractListModel
bool setData(const QModelIndex &index, const QVariant &value, int role);
/**
- * Makes sure the items are checkable.
+ * Makes sure the items are checkable and names editable.
*/
Qt::ItemFlags flags(const QModelIndex &index) const;
View
9 src/tiled/mapdocument.cpp
@@ -41,6 +41,8 @@
#include "resizelayer.h"
#include "resizemap.h"
#include "staggeredrenderer.h"
+#include "terrain.h"
+#include "terrainmodel.h"
#include "tile.h"
#include "tilelayer.h"
#include "tilesetmanager.h"
@@ -59,6 +61,7 @@ MapDocument::MapDocument(Map *map, const QString &fileName):
mMap(map),
mLayerModel(new LayerModel(this)),
mMapObjectModel(new MapObjectModel(this)),
+ mTerrainModel(new TerrainModel(this, this)),
mUndoStack(new QUndoStack(this))
{
switch (map->orientation()) {
@@ -489,6 +492,12 @@ void MapDocument::emitRegionEdited(const QRegion &region, Layer *layer)
emit regionEdited(region, layer);
}
+void MapDocument::emitTileTerrainChanged(const QList<Tile *> &tiles)
+{
+ if (!tiles.isEmpty())
+ emit tileTerrainChanged(tiles);
+}
+
/**
* Before forwarding the signal, the objects are removed from the list of
* selected objects, triggering a selectedObjectsChanged signal when
View
22 src/tiled/mapdocument.h
@@ -40,13 +40,16 @@ namespace Tiled {
class Map;
class MapObject;
class MapRenderer;
+class Terrain;
+class Tile;
class Tileset;
namespace Internal {
class LayerModel;
-class TileSelectionModel;
class MapObjectModel;
+class TerrainModel;
+class TileSelectionModel;
/**
* Represents an editable map. The purpose of this class is to make sure that
@@ -163,6 +166,8 @@ class MapDocument : public QObject
MapObjectModel *mapObjectModel() const { return mMapObjectModel; }
+ TerrainModel *terrainModel() const { return mTerrainModel; }
+
/**
* Returns the map renderer.
*/
@@ -225,6 +230,12 @@ class MapDocument : public QObject
void emitRegionEdited(const QRegion &region, Layer *layer);
/**
+ * Emits the signal notifying tileset models about changes to tile terrain
+ * information. All the \a tiles need to be from the same tileset.
+ */
+ void emitTileTerrainChanged(const QList<Tile*> &tiles);
+
+ /**
* Emits the editLayerNameRequested signal, to get renamed.
*/
inline void emitEditLayerNameRequested()
@@ -281,6 +292,12 @@ class MapDocument : public QObject
*/
void regionEdited(const QRegion &region, Layer *layer);
+ /**
+ * Emitted when the terrain information for the given list of tiles was
+ * changed. All the tiles are guaranteed to be from the same tileset.
+ */
+ void tileTerrainChanged(const QList<Tile*> &tiles);
+
void tilesetAdded(int index, Tileset *tileset);
void tilesetRemoved(Tileset *tileset);
void tilesetMoved(int from, int to);
@@ -305,7 +322,7 @@ private slots:
QString mFileName;
- /**
+ /*
* The filename of a plugin is unique. So it can be used to determine
* the right plugin to be used for saving the map again.
* The nameFilter of a plugin can not be used, since it's translatable.
@@ -320,6 +337,7 @@ private slots:
MapRenderer *mRenderer;
int mCurrentLayerIndex;
MapObjectModel *mMapObjectModel;
+ TerrainModel *mTerrainModel;
QUndoStack *mUndoStack;
};
View
4 src/tiled/mapobjectmodel.cpp
@@ -104,9 +104,9 @@ QModelIndex MapObjectModel::index(int row, int column,
QModelIndex MapObjectModel::parent(const QModelIndex &index) const
{
- MapObject *mapObject = toMapObject(index);
- if (mapObject)
+ if (MapObject *mapObject = toMapObject(index))
return this->index(mapObject->objectGroup());
+
return QModelIndex();
}
View
5 src/tiled/mapobjectmodel.h
@@ -34,6 +34,11 @@ namespace Internal {
class MapDocument;
+/**
+ * Provides a tree view on the objects present on a map. Also has member
+ * functions to modify objects that emit the appropriate signals to allow
+ * the UI to update.
+ */
class MapObjectModel : public QAbstractItemModel
{
Q_OBJECT
View
354 src/tiled/terraindock.cpp
@@ -23,97 +23,34 @@
#include "terraindock.h"
-#include "addremovemapobject.h"
-#include "addremovetileset.h"
#include "documentmanager.h"
-#include "erasetiles.h"
-#include "map.h"
-#include "mapdocument.h"
-#include "mapobject.h"
-#include "movetileset.h"
-#include "objectgroup.h"
-#include "propertiesdialog.h"
-#include "terrain.h"
-#include "tile.h"
-#include "tilelayer.h"
-#include "tileset.h"
#include "terrainmodel.h"
#include "terrainview.h"
-#include "tilesetmanager.h"
-#include "tmxmapwriter.h"
-#include "utils.h"
-#include <QMimeData>
-#include <QAction>
-#include <QDropEvent>
-#include <QFileDialog>
+#include <QEvent>
#include <QHBoxLayout>
-#include <QInputDialog>
-#include <QMenu>
-#include <QMessageBox>
-#include <QSignalMapper>
-#include <QStackedWidget>
-#include <QToolBar>
-#include <QToolButton>
-#include <QUrl>
-#include <QVBoxLayout>
+#include <QTreeView>
using namespace Tiled;
using namespace Tiled::Internal;
TerrainDock::TerrainDock(QWidget *parent):
QDockWidget(parent),
mMapDocument(0),
- mTabBar(new QTabBar),
- mViewStack(new QStackedWidget),
- mCurrentTerrain(0),
- mTerrainMenuButton(new QToolButton(this)),
- mTerrainMenu(new QMenu(this)),
- mTerrainMenuMapper(0)
+ mTerrainView(new TerrainView),
+ mCurrentTerrain(0)
{
setObjectName(QLatin1String("TerrainDock"));
- mTabBar->setMovable(true);
- mTabBar->setUsesScrollButtons(true);
-
- connect(mTabBar, SIGNAL(currentChanged(int)),
- SLOT(updateActions()));
- connect(mTabBar, SIGNAL(currentChanged(int)),
- mViewStack, SLOT(setCurrentIndex(int)));
- connect(mTabBar, SIGNAL(tabMoved(int,int)),
- this, SLOT(moveTileset(int,int)));
-
QWidget *w = new QWidget(this);
- QHBoxLayout *horizontal = new QHBoxLayout();
+ QHBoxLayout *horizontal = new QHBoxLayout(w);
horizontal->setSpacing(5);
- horizontal->addWidget(mTabBar);
- horizontal->addWidget(mTerrainMenuButton);
-
- QVBoxLayout *vertical = new QVBoxLayout(w);
- vertical->setSpacing(5);
- vertical->setMargin(5);
- vertical->addLayout(horizontal);
- vertical->addWidget(mViewStack);
-
- connect(mViewStack, SIGNAL(currentChanged(int)),
- this, SLOT(updateCurrentTiles()));
-
- connect(TilesetManager::instance(), SIGNAL(tilesetChanged(Tileset*)),
- this, SLOT(tilesetChanged(Tileset*)));
-
- connect(DocumentManager::instance(), SIGNAL(documentCloseRequested(int)),
- SLOT(documentCloseRequested(int)));
-
- mTerrainMenuButton->setMenu(mTerrainMenu);
- mTerrainMenuButton->setPopupMode(QToolButton::InstantPopup);
- mTerrainMenuButton->setAutoRaise(true);
- connect(mTerrainMenu, SIGNAL(aboutToShow()), SLOT(refreshTerrainMenu()));
+ horizontal->setMargin(5);
+ horizontal->addWidget(mTerrainView);
setWidget(w);
retranslateUi();
- setAcceptDrops(true);
- updateActions();
}
TerrainDock::~TerrainDock()
@@ -125,46 +62,25 @@ void TerrainDock::setMapDocument(MapDocument *mapDocument)
if (mMapDocument == mapDocument)
return;
- if (mMapDocument)
- mCurrentTilesets.insert(mMapDocument,
- mTabBar->tabText(mTabBar->currentIndex()));
- // Clear previous content
- while (mTabBar->count())
- mTabBar->removeTab(0);
- while (mViewStack->currentWidget())
- delete mViewStack->currentWidget();
-
// Clear all connections to the previous document
if (mMapDocument)
mMapDocument->disconnect(this);
mMapDocument = mapDocument;
+ QItemSelectionModel *oldSelectionModel = mTerrainView->selectionModel();
if (mMapDocument) {
- Map *map = mMapDocument->map();
- foreach (Tileset *tileset, map->tilesets())
- insertTilesetView(mTabBar->count(), tileset);
-
- connect(mMapDocument, SIGNAL(tilesetAdded(int,Tileset*)),
- SLOT(insertTilesetView(int,Tileset*)));
- connect(mMapDocument, SIGNAL(tilesetRemoved(Tileset*)),
- SLOT(tilesetRemoved(Tileset*)));
- connect(mMapDocument, SIGNAL(tilesetMoved(int,int)),
- SLOT(tilesetMoved(int,int)));
- connect(mMapDocument, SIGNAL(tilesetNameChanged(Tileset*)),
- SLOT(tilesetNameChanged(Tileset*)));
- connect(mMapDocument, SIGNAL(tilesetFileNameChanged(Tileset*)),
- SLOT(updateActions()));
-
- QString cacheName = mCurrentTilesets.take(mMapDocument);
- for (int i = 0; i < mTabBar->count(); ++i) {
- if (mTabBar->tabText(i) == cacheName) {
- mTabBar->setCurrentIndex(i);
- break;
- }
- }
+ mTerrainView->setMapDocument(mMapDocument);
+ mTerrainView->setModel(mMapDocument->terrainModel());
+ mTerrainView->expandAll();
+
+ connect(mTerrainView->selectionModel(),
+ SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
+ SLOT(currentRowChanged(QModelIndex)));
+ } else {
+ mTerrainView->setModel(0);
}
- updateActions();
+ delete oldSelectionModel;
}
void TerrainDock::changeEvent(QEvent *e)
@@ -179,197 +95,10 @@ void TerrainDock::changeEvent(QEvent *e)
}
}
-void TerrainDock::dragEnterEvent(QDragEnterEvent *e)
+void TerrainDock::currentRowChanged(const QModelIndex &index)
{
- const QList<QUrl> urls = e->mimeData()->urls();
- if (!urls.isEmpty() && !urls.at(0).toLocalFile().isEmpty())
- e->accept();
-}
-
-void TerrainDock::dropEvent(QDropEvent *)
-{
-/*
- QStringList paths;
- foreach (const QUrl &url, e->mimeData()->urls()) {
- const QString localFile = url.toLocalFile();
- if (!localFile.isEmpty())
- paths.append(localFile);
- }
- if (!paths.isEmpty()) {
- emit tilesetsDropped(paths);
- e->accept();
- }
-*/
-}
-
-
-void TerrainDock::insertTilesetView(int index, Tileset *tileset)
-{
- TerrainView *view = new TerrainView(mMapDocument);
- view->setModel(new TerrainModel(tileset, view));
-
- connect(view->selectionModel(),
- SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
- SLOT(updateCurrentTiles()));
-
- mTabBar->insertTab(index, tileset->name());
- mViewStack->insertWidget(index, view);
- updateActions();
-}
-
-void TerrainDock::updateActions()
-{
- const int index = mTabBar->currentIndex();
- if (index > -1)
- if (TerrainView *view = terrainViewAt(index))
- mViewStack->setCurrentWidget(view);
-}
-
-void TerrainDock::updateCurrentTiles()
-{
- const int viewIndex = mViewStack->currentIndex();
- if (viewIndex == -1)
- return;
-
- const QItemSelectionModel *s = terrainViewAt(viewIndex)->selectionModel();
- const QModelIndexList indexes = s->selection().indexes();
-
- if (indexes.isEmpty())
- return;
-
- const QModelIndex &first = indexes.first();
-
- const TerrainModel *model = static_cast<const TerrainModel*>(s->model());
- Terrain *terraion = model->terrainAt(first);
-
- setCurrentTerrain(terraion);
-}
-
-void TerrainDock::tilesetChanged(Tileset *tileset)
-{
- // Update the affected tileset model
- for (int i = 0; i < mViewStack->count(); ++i) {
- TerrainModel *model = terrainViewAt(i)->terrainModel();
- if (model->tileset() == tileset) {
- model->tilesetChanged();
- break;
- }
- }
-}
-
-void TerrainDock::tilesetRemoved(Tileset *tileset)
-{
- // Delete the related tileset view
- for (int i = 0; i < mViewStack->count(); ++i) {
- TerrainView *view = terrainViewAt(i);
- if (view->terrainModel()->tileset() == tileset) {
- mTabBar->removeTab(i);
- delete view;
- break;
- }
- }
-
- if (mCurrentTerrain && mCurrentTerrain->tileset() == tileset)
- setCurrentTerrain(NULL);
-}
-
-void TerrainDock::tilesetMoved(int from, int to)
-{
- // Move the related tileset views
- QWidget *widget = mViewStack->widget(from);
- mViewStack->removeWidget(widget);
- mViewStack->insertWidget(to, widget);
- mViewStack->setCurrentIndex(mTabBar->currentIndex());
-
- // Update the titles of the affected tabs
- const int start = qMin(from, to);
- const int end = qMax(from, to);
- for (int i = start; i <= end; ++i) {
- const Tileset *tileset = terrainViewAt(i)->terrainModel()->tileset();
- if (mTabBar->tabText(i) != tileset->name())
- mTabBar->setTabText(i, tileset->name());
- }
-}
-
-void TerrainDock::tilesetNameChanged(Tileset *tileset)
-{
- for (int i = 0; i < mTabBar->count(); i++) {
- TerrainView *view = terrainViewAt(i);
- if (tileset == view->terrainModel()->tileset()) {
- mTabBar->setTabText(i, tileset->name());
- return;
- }
- }
-}
-
-/**
- * Removes the currently selected tileset.
- */
-void TerrainDock::removeTileset()
-{
- const int currentIndex = mViewStack->currentIndex();
- if (currentIndex != -1)
- removeTileset(mViewStack->currentIndex());
-}
-
-/**
- * Removes the tileset at the given index. Prompting the user when the tileset
- * is in use by the map.
- */
-void TerrainDock::removeTileset(int index)
-{
- Tileset *tileset = terrainViewAt(index)->terrainModel()->tileset();
- const bool inUse = mMapDocument->map()->isTilesetUsed(tileset);
-
- // If the tileset is in use, warn the user and confirm removal
- if (inUse) {
- QMessageBox warning(QMessageBox::Warning,
- tr("Remove Tileset"),
- tr("The tileset \"%1\" is still in use by the "
- "map!").arg(tileset->name()),
- QMessageBox::Yes | QMessageBox::No,
- this);
- warning.setDefaultButton(QMessageBox::Yes);
- warning.setInformativeText(tr("Remove this tileset and all references "
- "to the tiles in this tileset?"));
-
- if (warning.exec() != QMessageBox::Yes)
- return;
- }
-
- QUndoCommand *remove = new RemoveTileset(mMapDocument, index, tileset);
- QUndoStack *undoStack = mMapDocument->undoStack();
-
- if (inUse) {
- // Remove references to tiles in this tileset from the current map
- undoStack->beginMacro(remove->text());
- foreach (Layer *layer, mMapDocument->map()->layers()) {
- if (TileLayer *tileLayer = layer->asTileLayer()) {
- const QRegion refs = tileLayer->tilesetReferences(tileset);
- if (!refs.isEmpty()) {
- undoStack->push(new EraseTiles(mMapDocument,
- tileLayer, refs));
- }
- } else if (ObjectGroup *objectGroup = layer->asObjectGroup()) {
- foreach (MapObject *object, objectGroup->objects()) {
- const Tile *tile = object->tile();
- if (tile && tile->tileset() == tileset) {
- undoStack->push(new RemoveMapObject(mMapDocument,
- object));
- }
- }
- }
- }
- }
- undoStack->push(remove);
- if (inUse)
- undoStack->endMacro();
-}
-
-void TerrainDock::moveTileset(int from, int to)
-{
- QUndoCommand *command = new MoveTileset(mMapDocument, from, to);
- mMapDocument->undoStack()->push(command);
+ if (Terrain *terrain = mMapDocument->terrainModel()->terrainAt(index))
+ setCurrentTerrain(terrain);
}
void TerrainDock::setCurrentTerrain(Terrain *terrain)
@@ -385,44 +114,3 @@ void TerrainDock::retranslateUi()
{
setWindowTitle(tr("Terrains"));
}
-
-Tileset *TerrainDock::currentTileset() const
-{
- if (QWidget *widget = mViewStack->currentWidget())
- return static_cast<TerrainView *>(widget)->terrainModel()->tileset();
-
- return 0;
-}
-
-TerrainView *TerrainDock::terrainViewAt(int index) const
-{
- return static_cast<TerrainView *>(mViewStack->widget(index));
-}
-
-void TerrainDock::documentCloseRequested(int index)
-{
- DocumentManager *documentManager = DocumentManager::instance();
- mCurrentTilesets.remove(documentManager->documents().at(index));
-}
-
-void TerrainDock::refreshTerrainMenu()
-{
- mTerrainMenu->clear();
-
- if (mTerrainMenuMapper) {
- mTabBar->disconnect(mTerrainMenuMapper);
- delete mTerrainMenuMapper;
- }
-
- mTerrainMenuMapper = new QSignalMapper(this);
- connect(mTerrainMenuMapper, SIGNAL(mapped(int)),
- mTabBar, SLOT(setCurrentIndex(int)));
-
- for (int i = 0; i < mTabBar->count(); ++i) {
- const QString name = mTabBar->tabText(i);
- QAction *action = new QAction(name, this);
- mTerrainMenu->addAction(action);
- connect(action, SIGNAL(triggered()), mTerrainMenuMapper, SLOT(map()));
- mTerrainMenuMapper->setMapping(action, i);
- }
-}
View
51 src/tiled/terraindock.h
@@ -27,19 +27,10 @@
#include <QDockWidget>
#include <QMap>
-class QAction;
-class QMenu;
-class QTabBar;
-class QToolBar;
-class QToolButton;