Skip to content

Commit

Permalink
Allow creating empty tilesets and adding images later
Browse files Browse the repository at this point in the history
Sponsored-by: Jamie Rocks
  • Loading branch information
bjorn committed Jul 21, 2013
1 parent ceeeb10 commit 074abd8
Show file tree
Hide file tree
Showing 13 changed files with 494 additions and 66 deletions.
2 changes: 2 additions & 0 deletions src/libtiled/tile.h
Expand Up @@ -160,6 +160,8 @@ class TILEDSHARED_EXPORT Tile : public Object
QString mImageSource;
unsigned mTerrain;
float mTerrainProbability;

friend class Tileset; // To allow changing the tile id
};

} // namespace Tiled
Expand Down
25 changes: 0 additions & 25 deletions src/libtiled/tilelayer.cpp
Expand Up @@ -275,31 +275,6 @@ bool TileLayer::referencesTileset(const Tileset *tileset) const
return false;
}

namespace {

class ReferencesTileset
{
public:
explicit ReferencesTileset(Tileset *tileset) : mTileset(tileset) {}

bool operator() (const Cell &cell) const
{
if (const Tile *tile = cell.tile)
return tile->tileset() == mTileset;
return false;
}

private:
Tileset *mTileset;
};

} // anonymous namespace

QRegion TileLayer::tilesetReferences(Tileset *tileset) const
{
return region(ReferencesTileset(tileset));
}

void TileLayer::removeReferencesToTileset(Tileset *tileset)
{
for (int i = 0, i_end = mGrid.size(); i < i_end; ++i) {
Expand Down
22 changes: 18 additions & 4 deletions src/libtiled/tilelayer.h
Expand Up @@ -211,14 +211,16 @@ class TILEDSHARED_EXPORT TileLayer : public Layer
QSet<Tileset*> usedTilesets() const;

/**
* Returns whether this tile layer is referencing the given tileset.
* Returns whether this tile layer has any cell for which the given
* \a condition returns true.
*/
bool referencesTileset(const Tileset *tileset) const;
template<typename Condition>
bool hasCell(Condition condition) const;

/**
* Returns the region of tiles coming from the given \a tileset.
* Returns whether this tile layer is referencing the given tileset.
*/
QRegion tilesetReferences(Tileset *tileset) const;
bool referencesTileset(const Tileset *tileset) const;

/**
* Removes all references to the given tileset. This sets all tiles on this
Expand Down Expand Up @@ -275,6 +277,7 @@ class TILEDSHARED_EXPORT TileLayer : public Layer
QVector<Cell> mGrid;
};


template<typename Condition>
QRegion TileLayer::region(Condition condition) const
{
Expand All @@ -299,6 +302,17 @@ QRegion TileLayer::region(Condition condition) const
return region;
}

template<typename Condition>
bool TileLayer::hasCell(Condition condition) const
{
for (int i = 0, i_end = mGrid.size(); i < i_end; ++i)
if (condition(mGrid.at(i)))
return true;

return false;
}


static inline bool cellInUse(const Cell &cell) { return !cell.isEmpty(); }

inline QRegion TileLayer::region() const
Expand Down
36 changes: 32 additions & 4 deletions src/libtiled/tileset.cpp
Expand Up @@ -281,6 +281,33 @@ Tile *Tileset::addTile(const QPixmap &image, const QString &source)
return newTile;
}

void Tileset::insertTiles(int index, const QList<Tile *> &tiles)
{
const int count = tiles.count();
for (int i = 0; i < count; ++i)
mTiles.insert(index + i, tiles.at(i));

// Adjust the tile IDs of the remaining tiles
for (int i = index + count; i < mTiles.size(); ++i)
mTiles.at(i)->mId += count;

updateTileSize();
}

void Tileset::removeTiles(int index, int count)
{
const QList<Tile*>::iterator first = mTiles.begin() + index;

QList<Tile*>::iterator last = first + count;
last = mTiles.erase(first, last);

// Adjust the tile IDs of the remaining tiles
for (; last != mTiles.end(); ++last)
(*last)->mId -= count;

updateTileSize();
}

void Tileset::setTileImage(int id, const QPixmap &image,
const QString &source)
{
Expand Down Expand Up @@ -319,10 +346,11 @@ void Tileset::updateTileSize()
int maxWidth = 0;
int maxHeight = 0;
foreach (Tile *tile, mTiles) {
if (maxWidth < tile->width())
maxWidth = tile->width();
if (maxHeight < tile->height())
maxHeight = tile->height();
const QSize size = tile->size();
if (maxWidth < size.width())
maxWidth = size.width();
if (maxHeight < size.height())
maxHeight = size.height();
}
mTileWidth = maxWidth;
mTileHeight = maxHeight;
Expand Down
3 changes: 3 additions & 0 deletions src/libtiled/tileset.h
Expand Up @@ -280,6 +280,9 @@ class TILEDSHARED_EXPORT Tileset : public Object
*/
Tile *addTile(const QPixmap &image, const QString &source = QString());

void insertTiles(int index, const QList<Tile*> &tiles);
void removeTiles(int index, int count);

/**
* Set the \a image to be used for the tile with the given \a id.
*/
Expand Down
88 changes: 88 additions & 0 deletions src/tiled/addremovetiles.cpp
@@ -0,0 +1,88 @@
/*
* addremovetiles.cpp
* Copyright 2013, 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 "addremovetiles.h"

#include "mapdocument.h"
#include "tile.h"
#include "tileset.h"

#include <QCoreApplication>

namespace Tiled {
namespace Internal {

AddRemoveTiles::AddRemoveTiles(MapDocument *mapDocument,
Tileset *tileset,
int index,
int count,
const QList<Tile *> &tiles)
: mMapDocument(mapDocument)
, mTileset(tileset)
, mIndex(index)
, mCount(count)
, mTiles(tiles)
{
}

AddRemoveTiles::~AddRemoveTiles()
{
qDeleteAll(mTiles);
}

void AddRemoveTiles::addTiles()
{
mTileset->insertTiles(mIndex, mTiles);
mTiles.clear();
mMapDocument->emitTilesetChanged(mTileset);
}

void AddRemoveTiles::removeTiles()
{
mTiles = mTileset->tiles().mid(mIndex, mCount);
mTileset->removeTiles(mIndex, mCount);
mMapDocument->emitTilesetChanged(mTileset);
}


AddTiles::AddTiles(MapDocument *mapDocument,
Tileset *tileset,
const QList<Tile *> &tiles)
: AddRemoveTiles(mapDocument,
tileset,
tileset->tileCount(),
tiles.count(),
tiles)
{
setText(QCoreApplication::translate("Undo Commands", "Add Tiles"));
}


RemoveTiles::RemoveTiles(MapDocument *mapDocument,
Tileset *tileset,
int index,
int count)
: AddRemoveTiles(mapDocument, tileset, index, count)
{
setText(QCoreApplication::translate("Undo Commands", "Remove Tiles"));
}

} // namespace Internal
} // namespace Tiled
99 changes: 99 additions & 0 deletions src/tiled/addremovetiles.h
@@ -0,0 +1,99 @@
/*
* addremovetiles.h
* Copyright 2013, 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 ADDREMOVETILES_H
#define ADDREMOVETILES_H

#include <QUndoCommand>

namespace Tiled {

class Tile;
class Tileset;

namespace Internal {

class MapDocument;

/**
* Abstract base class for AddTiles and RemoveTiles.
*/
class AddRemoveTiles : public QUndoCommand
{
public:
AddRemoveTiles(MapDocument *mapDocument,
Tileset *tileset,
int index,
int count,
const QList<Tile*> &tiles = QList<Tile*>());

~AddRemoveTiles();

protected:
void addTiles();
void removeTiles();

private:
MapDocument *mMapDocument;
Tileset *mTileset;
int mIndex;
int mCount;
QList<Tile*> mTiles;
};

/**
* Undo command that adds tiles to a tileset.
*/
class AddTiles : public AddRemoveTiles
{
public:
AddTiles(MapDocument *mapDocument,
Tileset *tileset,
const QList<Tile*> &tiles);

void undo()
{ removeTiles(); }

void redo()
{ addTiles(); }
};

/**
* Undo command that removes tiles from a tileset.
*/
class RemoveTiles : public AddRemoveTiles
{
public:
RemoveTiles(MapDocument *mapDocument,
Tileset *tileset,
int index,
int count);

void undo()
{ addTiles(); }

void redo()
{ removeTiles(); }
};

} // namespace Internal
} // namespace Tiled

#endif // TILED_INTERNAL_ADDREMOVETILES_H
12 changes: 12 additions & 0 deletions src/tiled/mapdocument.cpp
Expand Up @@ -568,6 +568,18 @@ void MapDocument::unifyTilesets(Map *map)
}
}

/**
* Emits the tileset changed signal. This signal is currently used when adding
* or removing tiles from a tileset.
*
* @todo Emit more specific signals.
*/
void MapDocument::emitTilesetChanged(Tileset *tileset)
{
Q_ASSERT(mMap->tilesets().contains(tileset));
emit tilesetChanged(tileset);
}

/**
* Before forwarding the signal, the objects are removed from the list of
* selected objects, triggering a selectedObjectsChanged signal when
Expand Down
2 changes: 2 additions & 0 deletions src/tiled/mapdocument.h
Expand Up @@ -234,6 +234,7 @@ class MapDocument : public QObject
void emitMapChanged();
void emitRegionChanged(const QRegion &region);
void emitRegionEdited(const QRegion &region, Layer *layer);
void emitTilesetChanged(Tileset *tileset);
void emitTileTerrainChanged(const QList<Tile*> &tiles);
void emitObjectGroupChanged(ObjectGroup *objectGroup);
void emitImageLayerChanged(ImageLayer *imageLayer);
Expand Down Expand Up @@ -320,6 +321,7 @@ class MapDocument : public QObject
void tilesetFileNameChanged(Tileset *tileset);
void tilesetNameChanged(Tileset *tileset);
void tilesetTileOffsetChanged(Tileset *tileset);
void tilesetChanged(Tileset *tileset);

void objectsAdded(const QList<MapObject*> &objects);
void objectsInserted(ObjectGroup *objectGroup, int first, int last);
Expand Down

0 comments on commit 074abd8

Please sign in to comment.