Skip to content
Permalink
Browse files

Fixed undo for terrain brush on previously empty area

Since change 6ca522e, the source tile
layer used for TileLayer::setCells can have 0 width and height, but when
a non-empty region is given alongside that means we want to erase that
region.

Now there exists two overloads for TileLayer::setCells, one that works
as before based on the size of the given layer, and one that always sets
all cells in the given area. There did not appear to be a use-case for
doing the intersection.
  • Loading branch information...
bjorn committed Oct 17, 2019
1 parent d6e3f0c commit 5135b3f3dc1400f3d524a84da21b0408f9508472
Showing with 27 additions and 21 deletions.
  1. +3 −8 src/libtiled/tilelayer.cpp
  2. +13 −5 src/libtiled/tilelayer.h
  3. +10 −5 src/tiled/tilelayeredit.cpp
  4. +1 −3 src/tiled/tilepainter.cpp
@@ -251,18 +251,13 @@ void TileLayer::merge(QPoint pos, const TileLayer *layer)
}

void TileLayer::setCells(int x, int y, const TileLayer *layer,
const QRegion &mask)
const QRegion &area)
{
QRegion targetArea = layer->localBounds().translated(x, y);

if (!mask.isEmpty())
targetArea &= mask;

#if QT_VERSION < 0x050800
const auto rects = targetArea.rects();
const auto rects = area.rects();
for (const QRect &rect : rects)
#else
for (const QRect &rect : targetArea)
for (const QRect &rect : area)
#endif
for (int _x = rect.left(); _x <= rect.right(); ++_x)
for (int _y = rect.top(); _y <= rect.bottom(); ++_y)
@@ -412,15 +412,17 @@ class TILEDSHARED_EXPORT TileLayer : public Layer

void clear();

/**
* Sets the cells within the given \a area to the cells in the given
* \a tileLayer. The tiles in \a tileLayer are offset by \a x and \a y.
*/
void setCells(int x, int y, const TileLayer *tileLayer, const QRegion &area);

/**
* Sets the cells starting at the given position to the cells in the given
* \a tileLayer.
*
* When a \a mask is given, only cells that fall within this mask are set.
* The mask is applied in local coordinates.
*/
void setCells(int x, int y, const TileLayer *tileLayer,
const QRegion &mask = QRegion());
void setCells(int x, int y, const TileLayer *tileLayer);

void setTiles(const QRegion &area, Tile *tile);

@@ -642,6 +644,12 @@ inline const Cell &TileLayer::cellAt(QPoint point) const
return cellAt(point.x(), point.y());
}

inline void TileLayer::setCells(int x, int y, const TileLayer *tileLayer)
{
setCells(x, y, tileLayer,
QRect(x, y, tileLayer->width(), tileLayer->height()));
}

typedef QSharedPointer<TileLayer> SharedTileLayer;

} // namespace Tiled
@@ -60,8 +60,17 @@ void TileLayerEdit::setTile(int x, int y, EditableTile *tile, int flags)

void TileLayerEdit::apply()
{
// Applying an edit automatically makes it mergeable, so that further
// changes made through the same edit are merged by default.
bool mergeable = std::exchange(mMergeable, true);

// Determine painted region and normalize the changes layer
auto paintedRegion = mChanges.region([] (const Cell &cell) { return cell.checked(); });

// If the painted region is empty there's nothing else to do
if (paintedRegion.isEmpty())
return;

auto rect = paintedRegion.boundingRect();
mChanges.resize(rect.size(), -rect.topLeft());

@@ -73,7 +82,7 @@ void TileLayerEdit::apply()
rect.x(), rect.y(),
&mChanges,
paintedRegion);
paint->setMergeable(mMergeable);
paint->setMergeable(mergeable);

// Add any used tilesets that aren't yet part of the target map
const auto tilesets = mChanges.usedTilesets();
@@ -89,10 +98,6 @@ void TileLayerEdit::apply()
}

mChanges.clear();

// Applying an edit automatically makes it mergeable, so that further
// changes made through the same edit are merged by default.
mMergeable = true;
}

} // namespace Tiled
@@ -102,9 +102,7 @@ void TilePainter::setCells(int x, int y,
TileLayer *tileLayer,
const QRegion &mask)
{
QRegion region = paintableRegion(tileLayer->localBounds().translated(x, y));
region &= mask;

QRegion region = paintableRegion(mask);
if (region.isEmpty())
return;

0 comments on commit 5135b3f

Please sign in to comment.
You can’t perform that action at this time.