Skip to content

Commit

Permalink
Added ability to reorder terrains (#1802)
Browse files Browse the repository at this point in the history
Closes #1603
  • Loading branch information
dorkster authored and bjorn committed Oct 30, 2017
1 parent 2863786 commit affec43
Show file tree
Hide file tree
Showing 12 changed files with 286 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/libtiled/tileset.cpp
Expand Up @@ -410,6 +410,31 @@ Terrain *Tileset::takeTerrainAt(int index)
return terrain;
}

/**
* Swaps a terrain type at \a index with another index.
*/
void Tileset::swapTerrains(int index, int swapIndex)
{
mTerrainTypes.swap(index, swapIndex);

// Reassign terrain IDs
mTerrainTypes.at(index)->mId = index;
mTerrainTypes.at(swapIndex)->mId = swapIndex;

// Clear and adjust tile terrain references
for (Tile *tile : mTiles) {
for (int corner = 0; corner < 4; ++corner) {
const int terrainId = tile->cornerTerrainId(corner);
if (terrainId == index)
tile->setCornerTerrainId(corner, swapIndex);
else if (terrainId == swapIndex)
tile->setCornerTerrainId(corner, index);
}
}

mTerrainDistancesDirty = true;
}

/**
* Returns the transition penalty(/distance) between 2 terrains. -1 if no
* transition is possible.
Expand Down
1 change: 1 addition & 0 deletions src/libtiled/tileset.h
Expand Up @@ -183,6 +183,7 @@ class TILEDSHARED_EXPORT Tileset : public Object
Terrain *addTerrain(const QString &name, int imageTileId);
void insertTerrain(int index, Terrain *terrain);
Terrain *takeTerrainAt(int index);
void swapTerrains(int index, int swapIndex);

int terrainTransitionPenalty(int terrainType0, int terrainType1) const;
int maximumTerrainDistance() const;
Expand Down
68 changes: 68 additions & 0 deletions src/tiled/moveterrain.cpp
@@ -0,0 +1,68 @@
/*
* moveterrain.cpp
* Copyright 2012, Thorbjørn Lindeijer <thorbjorn@lindeijer.nl>
* Copyright 2017, Justin Jacobs <jajdorkster@gmail.com>
*
* 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 "moveterrain.h"

#include "terrain.h"
#include "tileset.h"
#include "tilesetdocument.h"
#include "tilesetterrainmodel.h"

#include <QCoreApplication>

using namespace Tiled;
using namespace Tiled::Internal;

MoveTerrain::MoveTerrain(TilesetDocument *tilesetDocument, int index)
: mTilesetDocument(tilesetDocument)
, mTileset(tilesetDocument->tileset().data())
, mIndex(index)
{
}

MoveTerrain::~MoveTerrain()
{
}

void MoveTerrain::moveTerrainUp()
{
mTilesetDocument->terrainModel()->swapTerrains(mIndex, mIndex - 1);
mIndex -= 1;
}

void MoveTerrain::moveTerrainDown()
{
mTilesetDocument->terrainModel()->swapTerrains(mIndex, mIndex + 1);
mIndex += 1;
}


MoveTerrainUp::MoveTerrainUp(TilesetDocument *tilesetDocument, Terrain *terrain)
: MoveTerrain(tilesetDocument, terrain->id())
{
setText(QCoreApplication::translate("Undo Commands", "Move Terrain Up"));
}

MoveTerrainDown::MoveTerrainDown(TilesetDocument *tilesetDocument, Terrain *terrain)
: MoveTerrain(tilesetDocument, terrain->id())
{
setText(QCoreApplication::translate("Undo Commands", "Move Terrain Down"));
}
81 changes: 81 additions & 0 deletions src/tiled/moveterrain.h
@@ -0,0 +1,81 @@
/*
* moveterrain.h
* Copyright 2012, Thorbjørn Lindeijer <thorbjorn@lindeijer.nl>
* Copyright 2017, Justin Jacobs <jajdorkster@gmail.com>
*
* 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/>.
*/

#pragma once

#include <QUndoCommand>

namespace Tiled {

class Terrain;
class Tileset;

namespace Internal {

class TilesetDocument;

/**
* Abstract base class for MoveTerrainUp and MoveTerrainDown.
*/
class MoveTerrain : public QUndoCommand
{
public:
MoveTerrain(TilesetDocument *tilesetDocument,
int index);
~MoveTerrain();

protected:
void moveTerrainUp();
void moveTerrainDown();

private:
TilesetDocument *mTilesetDocument;
Tileset *mTileset;
int mIndex;
};


/**
* Moves a terrain up in the list of terrains.
*/
class MoveTerrainUp : public MoveTerrain
{
public:
MoveTerrainUp(TilesetDocument *tilesetDocument, Terrain *terrain);

void undo() override { moveTerrainDown(); }
void redo() override { moveTerrainUp(); }
};

/**
* Moves a terrain down in the list of terrains.
*/
class MoveTerrainDown : public MoveTerrain
{
public:
MoveTerrainDown(TilesetDocument *tilesetDocument, Terrain *terrain);

void undo() override { moveTerrainUp(); }
void redo() override { moveTerrainDown(); }
};

} // namespace Internal
} // namespace Tiled
61 changes: 61 additions & 0 deletions src/tiled/terraindock.cpp
Expand Up @@ -26,6 +26,7 @@
#include "documentmanager.h"
#include "map.h"
#include "mapdocument.h"
#include "moveterrain.h"
#include "terrain.h"
#include "terrainmodel.h"
#include "terrainview.h"
Expand Down Expand Up @@ -106,6 +107,8 @@ TerrainDock::TerrainDock(QWidget *parent)
, mToolBar(new QToolBar(this))
, mAddTerrainType(new QAction(this))
, mRemoveTerrainType(new QAction(this))
, mMoveTerrainTypeUp(new QAction(this))
, mMoveTerrainTypeDown(new QAction(this))
, mDocument(nullptr)
, mCurrentTerrain(nullptr)
, mTilesetDocumentsFilterModel(new TilesetDocumentsFilterModel(this))
Expand Down Expand Up @@ -135,9 +138,13 @@ TerrainDock::TerrainDock(QWidget *parent)

mAddTerrainType->setIcon(QIcon(QStringLiteral(":/images/22x22/add.png")));
mRemoveTerrainType->setIcon(QIcon(QStringLiteral(":/images/22x22/remove.png")));
mMoveTerrainTypeUp->setIcon(QIcon(QStringLiteral(":/images/24x24/go-up.png")));
mMoveTerrainTypeDown->setIcon(QIcon(QStringLiteral(":/images/24x24/go-down.png")));

Utils::setThemeIcon(mAddTerrainType, "add");
Utils::setThemeIcon(mRemoveTerrainType, "remove");
Utils::setThemeIcon(mMoveTerrainTypeUp, "go-up");
Utils::setThemeIcon(mMoveTerrainTypeDown, "go-down");

connect(mEraseTerrainButton, &QPushButton::clicked,
this, &TerrainDock::eraseTerrainButtonClicked);
Expand All @@ -148,6 +155,8 @@ TerrainDock::TerrainDock(QWidget *parent)

mToolBar->addAction(mAddTerrainType);
mToolBar->addAction(mRemoveTerrainType);
mToolBar->addAction(mMoveTerrainTypeUp);
mToolBar->addAction(mMoveTerrainTypeDown);

QHBoxLayout *horizontal = new QHBoxLayout;
horizontal->addWidget(mEraseTerrainButton);
Expand All @@ -163,6 +172,10 @@ TerrainDock::TerrainDock(QWidget *parent)
this, &TerrainDock::addTerrainTypeRequested);
connect(mRemoveTerrainType, &QAction::triggered,
this, &TerrainDock::removeTerrainTypeRequested);
connect(mMoveTerrainTypeUp, &QAction::triggered,
this, &TerrainDock::moveTerrainTypeUp);
connect(mMoveTerrainTypeDown, &QAction::triggered,
this, &TerrainDock::moveTerrainTypeDown);

setWidget(w);
retranslateUi();
Expand Down Expand Up @@ -214,6 +227,13 @@ void TerrainDock::setDocument(Document *document)
connect(terrainModel, &TilesetTerrainModel::terrainRemoved,
this, &TerrainDock::refreshCurrentTerrain);

/*
* The current terrain does not change when moving terrains.
* We need to refresh this in order to disable the up/down buttons when
* appropriate.
*/
connect(terrainModel, &QAbstractItemModel::rowsMoved,
this, &TerrainDock::rowsMoved);
} else {
mProxyModel->setSourceModel(nullptr);
setCurrentTerrain(nullptr);
Expand Down Expand Up @@ -303,6 +323,11 @@ void TerrainDock::setCurrentTerrain(Terrain *terrain)

mRemoveTerrainType->setEnabled(terrain != nullptr);

mMoveTerrainTypeUp->setEnabled(terrain != nullptr &&
terrain->id() > 0);
mMoveTerrainTypeDown->setEnabled(terrain != nullptr &&
terrain->id() < mProxyModel->rowCount() - 1);

emit currentTerrainChanged(mCurrentTerrain);
}

Expand All @@ -313,6 +338,8 @@ void TerrainDock::retranslateUi()

mAddTerrainType->setText(tr("Add Terrain Type"));
mRemoveTerrainType->setText(tr("Remove Terrain Type"));
mMoveTerrainTypeUp->setText(tr("Move Terrain Type Up"));
mMoveTerrainTypeDown->setText(tr("Move Terrain Type Down"));
}

QModelIndex TerrainDock::terrainIndex(Terrain *terrain) const
Expand All @@ -326,3 +353,37 @@ QModelIndex TerrainDock::terrainIndex(Terrain *terrain) const

return mProxyModel->mapFromSource(sourceIndex);
}

void TerrainDock::moveTerrainTypeUp()
{
Terrain *terrain = currentTerrain();
if (!terrain)
return;

TilesetDocument* tilesetDocument = qobject_cast<TilesetDocument*>(mDocument);

if (terrain->id() == 0)
return;

tilesetDocument->undoStack()->push(new MoveTerrainUp(tilesetDocument, terrain));
}

void TerrainDock::moveTerrainTypeDown()
{
Terrain *terrain = currentTerrain();
if (!terrain)
return;

TilesetDocument* tilesetDocument = qobject_cast<TilesetDocument*>(mDocument);

if (terrain->id() == tilesetDocument->tileset().data()->terrainCount() - 1)
return;

tilesetDocument->undoStack()->push(new MoveTerrainDown(tilesetDocument, terrain));
}

void TerrainDock::rowsMoved()
{
mCurrentTerrain = nullptr;
refreshCurrentTerrain();
}
5 changes: 5 additions & 0 deletions src/tiled/terraindock.h
Expand Up @@ -93,15 +93,20 @@ private slots:
void indexPressed(const QModelIndex &index);
void expandRows(const QModelIndex &parent, int first, int last);
void eraseTerrainButtonClicked();
void rowsMoved();

private:
void retranslateUi();

QModelIndex terrainIndex(Terrain *terrain) const;
void moveTerrainTypeUp();
void moveTerrainTypeDown();

QToolBar *mToolBar;
QAction *mAddTerrainType;
QAction *mRemoveTerrainType;
QAction *mMoveTerrainTypeUp;
QAction *mMoveTerrainTypeDown;

Document *mDocument;
TerrainView *mTerrainView;
Expand Down
15 changes: 15 additions & 0 deletions src/tiled/terrainmodel.cpp
Expand Up @@ -202,6 +202,10 @@ void TerrainModel::onTilesetRowsInserted(const QModelIndex &parent, int first, i
this, &TerrainModel::onTerrainAboutToBeRemoved);
connect(tilesetTerrainModel, &TilesetTerrainModel::terrainRemoved,
this, &TerrainModel::onTerrainRemoved);
connect(tilesetTerrainModel, &TilesetTerrainModel::terrainAboutToBeSwapped,
this, &TerrainModel::onTerrainAboutToBeSwapped);
connect(tilesetTerrainModel, &TilesetTerrainModel::terrainSwapped,
this, &TerrainModel::onTerrainSwapped);
}
endInsertRows();
}
Expand Down Expand Up @@ -295,3 +299,14 @@ void TerrainModel::onTerrainRemoved(Terrain *terrain)
const QModelIndex index = TerrainModel::index(terrain->tileset());
emit dataChanged(index, index);
}

void TerrainModel::onTerrainAboutToBeSwapped(Tileset *tileset, int terrainId, int swapTerrainId)
{
QModelIndex parent = index(tileset);
beginMoveRows(parent, terrainId, terrainId, parent, swapTerrainId);
}

void TerrainModel::onTerrainSwapped()
{
endMoveRows();
}
2 changes: 2 additions & 0 deletions src/tiled/terrainmodel.h
Expand Up @@ -99,6 +99,8 @@ private slots:
void onTerrainAdded(Tileset *tileset);
void onTerrainAboutToBeRemoved(Terrain *terrain);
void onTerrainRemoved(Terrain *terrain);
void onTerrainAboutToBeSwapped(Tileset *tileset, int terrainId, int swapTerrainId);
void onTerrainSwapped();

private:
QAbstractItemModel *mTilesetDocumentsModel;
Expand Down
2 changes: 2 additions & 0 deletions src/tiled/tiled.pro
Expand Up @@ -171,6 +171,7 @@ SOURCES += aboutdialog.cpp \
movelayer.cpp \
movemapobject.cpp \
movemapobjecttogroup.cpp \
moveterrain.cpp \
newmapdialog.cpp \
newtemplatedialog.cpp \
newtilesetdialog.cpp \
Expand Down Expand Up @@ -366,6 +367,7 @@ HEADERS += aboutdialog.h \
movelayer.h \
movemapobject.h \
movemapobjecttogroup.h \
moveterrain.h \
newmapdialog.h \
newtemplatedialog.h \
newtilesetdialog.h \
Expand Down
2 changes: 2 additions & 0 deletions src/tiled/tiled.qbs
Expand Up @@ -269,6 +269,8 @@ QtGuiApplication {
"movemapobject.h",
"movemapobjecttogroup.cpp",
"movemapobjecttogroup.h",
"moveterrain.cpp",
"moveterrain.h",
"newmapdialog.cpp",
"newmapdialog.h",
"newmapdialog.ui",
Expand Down

0 comments on commit affec43

Please sign in to comment.